toolnet-memory 0.2.20 → 0.3.0

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/setup.js CHANGED
@@ -1,12 +1,57 @@
1
- import A from"node:fs";import ne from"node:os";import P from"node:path";import vo from"node:readline/promises";import{stdin as T,stdout as b}from"node:process";import{HeadBucketCommand as Vo,S3Client as Jo}from"@aws-sdk/client-s3";var le=[{id:"openai-compatible",label:"OpenAI-compatible",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"alibaba",label:"Alibaba / DashScope",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"openrouter",label:"OpenRouter",defaultBaseUrl:"https://openrouter.ai/api/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"groq",label:"Groq",defaultBaseUrl:"https://api.groq.com/openai/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"deepseek",label:"DeepSeek",defaultBaseUrl:"https://api.deepseek.com",defaultModel:"deepseek-v4-flash",requiresApiKey:!0,transport:"openai-compatible"},{id:"nvidia",label:"NVIDIA NIM",defaultBaseUrl:"https://integrate.api.nvidia.com/v1",defaultModel:"deepseek-ai/deepseek-v4-pro",requiresApiKey:!0,transport:"openai-compatible"},{id:"gemini",label:"Gemini",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta",requiresApiKey:!0,transport:"gemini"},{id:"huggingface",label:"Hugging Face",defaultBaseUrl:"https://router.huggingface.co/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"ollama",label:"Ollama / Local",defaultBaseUrl:"http://127.0.0.1:11434/v1",requiresApiKey:!1,transport:"openai-compatible"},{id:"custom",label:"Custom endpoint",requiresApiKey:!1,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"cloudflare",label:"Cloudflare Workers AI",requiresApiKey:!0,requiresAccountId:!0,transport:"cloudflare"}];function S(e){let o=le.find(t=>t.id===e);if(!o)throw new Error(`Unsupported AI provider: ${e}`);return o}function K(e){return le.some(o=>o.id===e)}function c(e){return process.env[e]?.trim()||void 0}function f(...e){return e.find(o=>!!o?.trim())}function ge(){if(c("GROQ_API_KEY"))return"groq";if(c("DEEPSEEK_API_KEY"))return"deepseek";if(c("NVIDIA_API_KEY")||c("NVIDIA_NIM_API_KEY"))return"nvidia";if(c("OPENROUTER_API_KEY"))return"openrouter";if(c("ALIBABA_API_KEY")||c("DASHSCOPE_API_KEY"))return"alibaba";if(c("GEMINI_API_KEY")||c("GOOGLE_API_KEY"))return"gemini";if(c("CLOUDFLARE_API_TOKEN")&&c("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(c("HF_TOKEN"))return"huggingface";if(c("OLLAMA_MODEL")||c("OLLAMA_BASE_URL"))return"ollama"}function de(){let e=c("TOOLNET_LLM_PROVIDER");return e&&K(e)?e:ge()??"openai-compatible"}function B(e){let o=S(e);switch(e){case"alibaba":return{provider:e,apiKey:f(c("ALIBABA_API_KEY"),c("DASHSCOPE_API_KEY")),baseUrl:f(c("ALIBABA_BASE_URL"),c("DASHSCOPE_BASE_URL"),o.defaultBaseUrl),model:f(c("ALIBABA_MODEL"),c("DASHSCOPE_MODEL"))};case"openrouter":return{provider:e,apiKey:c("OPENROUTER_API_KEY"),baseUrl:f(c("OPENROUTER_BASE_URL"),o.defaultBaseUrl),model:c("OPENROUTER_MODEL")};case"groq":return{provider:e,apiKey:c("GROQ_API_KEY"),baseUrl:f(c("GROQ_BASE_URL"),o.defaultBaseUrl),model:c("GROQ_MODEL")};case"deepseek":return{provider:e,apiKey:c("DEEPSEEK_API_KEY"),baseUrl:f(c("DEEPSEEK_BASE_URL"),o.defaultBaseUrl),model:f(c("DEEPSEEK_MODEL"),o.defaultModel)};case"nvidia":return{provider:e,apiKey:f(c("NVIDIA_API_KEY"),c("NVIDIA_NIM_API_KEY")),baseUrl:f(c("NVIDIA_BASE_URL"),c("NVIDIA_NIM_BASE_URL"),o.defaultBaseUrl),model:f(c("NVIDIA_MODEL"),c("NVIDIA_NIM_MODEL"),o.defaultModel)};case"gemini":return{provider:e,apiKey:f(c("GEMINI_API_KEY"),c("GOOGLE_API_KEY")),baseUrl:f(c("GEMINI_BASE_URL"),o.defaultBaseUrl),model:c("GEMINI_MODEL")};case"huggingface":return{provider:e,apiKey:c("HF_TOKEN"),baseUrl:f(c("HF_INFERENCE_BASE_URL"),o.defaultBaseUrl),model:f(c("HF_LLM_MODEL"),c("HF_MODEL"))};case"ollama":return{provider:e,apiKey:c("OLLAMA_API_KEY"),baseUrl:f(c("OLLAMA_BASE_URL"),o.defaultBaseUrl),model:c("OLLAMA_MODEL")};case"cloudflare":return{provider:e,accountId:c("CLOUDFLARE_ACCOUNT_ID"),apiKey:c("CLOUDFLARE_API_TOKEN"),baseUrl:c("CLOUDFLARE_AI_BASE_URL"),model:c("CLOUDFLARE_MODEL")};case"custom":return{provider:e,apiKey:c("CUSTOM_AI_API_KEY"),baseUrl:c("CUSTOM_AI_BASE_URL"),model:c("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:f(c("OPENAI_API_KEY"),c("MODEL_API_KEY")),baseUrl:f(c("OPENAI_BASE_URL"),c("MODEL_BASE_URL")),model:f(c("OPENAI_MODEL"),c("MODEL_NAME"))}}}function Je(){let e=c("TOOLNET_LLM_PROVIDER"),o=e&&K(e)?e:de(),t=S(o),n=B(o);return{provider:o,apiKey:f(c("TOOLNET_LLM_API_KEY"),n.apiKey),baseUrl:f(c("TOOLNET_LLM_BASE_URL"),n.baseUrl,t.defaultBaseUrl),model:f(c("TOOLNET_LLM_MODEL"),n.model,t.defaultModel),accountId:f(c("TOOLNET_LLM_ACCOUNT_ID"),n.accountId)}}function We(){let e=c("TOOLNET_EMBEDDING_PROVIDER");return e==="local"?"local":e&&K(e)?e:c("HF_TOKEN")||c("HF_EMBEDDING_MODEL")?"huggingface":"local"}function Xe(){let e=We();if(e==="local")return{provider:"local",model:f(c("TOOLNET_EMBEDDING_MODEL"),c("LOCAL_EMBEDDING_MODEL"))};let o=S(e),t,n,r,i;switch(e){case"huggingface":t=c("HF_TOKEN"),n=c("HF_INFERENCE_BASE_URL"),r=c("HF_EMBEDDING_MODEL");break;case"openai-compatible":t=c("OPENAI_API_KEY"),n=c("OPENAI_BASE_URL"),r=c("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":t=c("CLOUDFLARE_API_TOKEN"),n=c("CLOUDFLARE_AI_BASE_URL"),r=c("CLOUDFLARE_EMBEDDING_MODEL"),i=c("CLOUDFLARE_ACCOUNT_ID");break;default:t=B(e).apiKey,n=B(e).baseUrl,r=c(`${e.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let s=f(c("TOOLNET_EMBEDDING_ACCOUNT_ID"),i),a=f(c("TOOLNET_EMBEDDING_BASE_URL"),n,o.defaultBaseUrl),l=e==="cloudflare"&&!a&&s?`https://api.cloudflare.com/client/v4/accounts/${s}/ai/v1`:a;return{provider:e,apiKey:f(c("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:l,model:f(c("TOOLNET_EMBEDDING_MODEL"),r),accountId:s}}function ze(){let e=Je(),o=Xe();return{llm:e,embedding:o,legacy:{llm:!c("TOOLNET_LLM_PROVIDER")&&!!ge(),embedding:!c("TOOLNET_EMBEDDING_PROVIDER")&&!!(c("HF_TOKEN")||c("HF_EMBEDDING_MODEL"))}}}function Ee(e=de()){let o=ze().llm;if(e===o.provider)return{id:e,apiKey:o.apiKey,baseUrl:o.baseUrl,model:o.model,accountId:o.accountId};let t=B(e);return{id:e,apiKey:t.apiKey,baseUrl:t.baseUrl,model:t.model,accountId:t.accountId}}var v=class extends Error{status;constructor(o,t){super(o),this.name="AiHttpError",this.status=t}};async function y(e,o,t=3e4){let n=new AbortController,r=setTimeout(()=>n.abort(),t);r.unref?.();try{let i=await fetch(e,{...o,signal:n.signal}),s=await i.text();if(!i.ok){let a=s;try{let l=JSON.parse(s);a=l.error?.message??l.message??s}catch{}throw new v(a||`HTTP ${i.status}`,i.status)}return s.trim()?JSON.parse(s):{}}finally{clearTimeout(r)}}function w(e,o){return`${e.replace(/\/+$/,"")}/${o.replace(/^\/+/,"")}`}var k=class{constructor(o){this.config=o}config;id="cloudflare";model(){let o=this.config.model?.trim();if(!o)throw new Error("cloudflare: MODEL is not configured");return o}async generate(o){let t=this.config.accountId?.trim(),n=this.config.apiKey?.trim();if(!t)throw new Error("cloudflare: ACCOUNT ID is not configured");if(!n)throw new Error("cloudflare: API TOKEN is not configured");let r=this.model(),s=`${(this.config.baseUrl?.trim()||`https://api.cloudflare.com/client/v4/accounts/${t}/ai/run`).replace(/\/+$/,"")}/${r}`,a=await y(s,{method:"POST",headers:{authorization:`Bearer ${n}`,"content-type":"application/json",...this.config.headers},body:JSON.stringify({messages:o.messages,temperature:o.temperature,max_tokens:o.maxTokens})}),l=a.result?.response?.trim();if(!l)throw new Error(a.errors?.[0]?.message??"cloudflare: empty model response");return{text:l,provider:"cloudflare",model:r}}async healthCheck(){let o=Date.now();try{return{ok:!0,provider:"cloudflare",model:(await this.generate({messages:[{role:"user",content:"Reply exactly: OK"}],temperature:0,maxTokens:8})).model,message:"Provider reachable",latencyMs:Date.now()-o}}catch(t){return{ok:!1,provider:"cloudflare",model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-o}}}};var Y=class{constructor(o){this.config=o}config;id="gemini";model(){let o=this.config.model?.trim();if(!o)throw new Error("gemini: MODEL is not configured");return o.replace(/^models\//,"")}async generate(o){let t=this.config.apiKey?.trim();if(!t)throw new Error("gemini: API KEY is not configured");let n=this.config.baseUrl?.trim()||"https://generativelanguage.googleapis.com/v1beta",r=this.model(),i=o.messages.filter(E=>E.role==="system"),s=o.messages.filter(E=>E.role!=="system").map(E=>({role:E.role==="assistant"?"model":"user",parts:[{text:E.content}]})),a=`${w(n,`models/${encodeURIComponent(r)}:generateContent`)}?key=${encodeURIComponent(t)}`,l=await y(a,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...i.length?{systemInstruction:{parts:[{text:i.map(E=>E.content).join(`
1
+ import A from"node:fs";import _e from"node:os";import B from"node:path";import zt from"node:readline/promises";import{stdin as T,stdout as k}from"node:process";import{HeadBucketCommand as Qt,S3Client as Zt}from"@aws-sdk/client-s3";var Le=[{id:"openai-compatible",label:"OpenAI-compatible",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"alibaba",label:"Alibaba / DashScope",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"openrouter",label:"OpenRouter",defaultBaseUrl:"https://openrouter.ai/api/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"groq",label:"Groq",defaultBaseUrl:"https://api.groq.com/openai/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"deepseek",label:"DeepSeek",defaultBaseUrl:"https://api.deepseek.com",defaultModel:"deepseek-v4-flash",requiresApiKey:!0,transport:"openai-compatible"},{id:"nvidia",label:"NVIDIA NIM",defaultBaseUrl:"https://integrate.api.nvidia.com/v1",defaultModel:"deepseek-ai/deepseek-v4-pro",requiresApiKey:!0,transport:"openai-compatible"},{id:"gemini",label:"Gemini",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta",requiresApiKey:!0,transport:"gemini"},{id:"huggingface",label:"Hugging Face",defaultBaseUrl:"https://router.huggingface.co/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"ollama",label:"Ollama / Local",defaultBaseUrl:"http://127.0.0.1:11434/v1",requiresApiKey:!1,transport:"openai-compatible"},{id:"custom",label:"Custom endpoint",requiresApiKey:!1,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"cloudflare",label:"Cloudflare Workers AI",requiresApiKey:!0,requiresAccountId:!0,transport:"cloudflare"}];function S(e){let o=Le.find(t=>t.id===e);if(!o)throw new Error(`Unsupported AI provider: ${e}`);return o}function x(e){return Le.some(o=>o.id===e)}function l(e){return process.env[e]?.trim()||void 0}function u(...e){return e.find(o=>!!o?.trim())}function Te(){if(l("GROQ_API_KEY"))return"groq";if(l("DEEPSEEK_API_KEY"))return"deepseek";if(l("NVIDIA_API_KEY")||l("NVIDIA_NIM_API_KEY"))return"nvidia";if(l("OPENROUTER_API_KEY"))return"openrouter";if(l("ALIBABA_API_KEY")||l("DASHSCOPE_API_KEY"))return"alibaba";if(l("GEMINI_API_KEY")||l("GOOGLE_API_KEY"))return"gemini";if(l("CLOUDFLARE_API_TOKEN")&&l("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(l("HF_TOKEN"))return"huggingface";if(l("OLLAMA_MODEL")||l("OLLAMA_BASE_URL"))return"ollama"}function Ae(){let e=l("TOOLNET_LLM_PROVIDER");return e&&x(e)?e:Te()??"openai-compatible"}function $(e){let o=S(e);switch(e){case"alibaba":return{provider:e,apiKey:u(l("ALIBABA_API_KEY"),l("DASHSCOPE_API_KEY")),baseUrl:u(l("ALIBABA_BASE_URL"),l("DASHSCOPE_BASE_URL"),o.defaultBaseUrl),model:u(l("ALIBABA_MODEL"),l("DASHSCOPE_MODEL"))};case"openrouter":return{provider:e,apiKey:l("OPENROUTER_API_KEY"),baseUrl:u(l("OPENROUTER_BASE_URL"),o.defaultBaseUrl),model:l("OPENROUTER_MODEL")};case"groq":return{provider:e,apiKey:l("GROQ_API_KEY"),baseUrl:u(l("GROQ_BASE_URL"),o.defaultBaseUrl),model:l("GROQ_MODEL")};case"deepseek":return{provider:e,apiKey:l("DEEPSEEK_API_KEY"),baseUrl:u(l("DEEPSEEK_BASE_URL"),o.defaultBaseUrl),model:u(l("DEEPSEEK_MODEL"),o.defaultModel)};case"nvidia":return{provider:e,apiKey:u(l("NVIDIA_API_KEY"),l("NVIDIA_NIM_API_KEY")),baseUrl:u(l("NVIDIA_BASE_URL"),l("NVIDIA_NIM_BASE_URL"),o.defaultBaseUrl),model:u(l("NVIDIA_MODEL"),l("NVIDIA_NIM_MODEL"),o.defaultModel)};case"gemini":return{provider:e,apiKey:u(l("GEMINI_API_KEY"),l("GOOGLE_API_KEY")),baseUrl:u(l("GEMINI_BASE_URL"),o.defaultBaseUrl),model:l("GEMINI_MODEL")};case"huggingface":return{provider:e,apiKey:l("HF_TOKEN"),baseUrl:u(l("HF_INFERENCE_BASE_URL"),o.defaultBaseUrl),model:u(l("HF_LLM_MODEL"),l("HF_MODEL"))};case"ollama":return{provider:e,apiKey:l("OLLAMA_API_KEY"),baseUrl:u(l("OLLAMA_BASE_URL"),o.defaultBaseUrl),model:l("OLLAMA_MODEL")};case"cloudflare":return{provider:e,accountId:l("CLOUDFLARE_ACCOUNT_ID"),apiKey:l("CLOUDFLARE_API_TOKEN"),baseUrl:l("CLOUDFLARE_AI_BASE_URL"),model:l("CLOUDFLARE_MODEL")};case"custom":return{provider:e,apiKey:l("CUSTOM_AI_API_KEY"),baseUrl:l("CUSTOM_AI_BASE_URL"),model:l("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:u(l("OPENAI_API_KEY"),l("MODEL_API_KEY")),baseUrl:u(l("OPENAI_BASE_URL"),l("MODEL_BASE_URL")),model:u(l("OPENAI_MODEL"),l("MODEL_NAME"))}}}function Ro(){let e=l("TOOLNET_LLM_PROVIDER"),o=e&&x(e)?e:Ae(),t=S(o),n=$(o);return{provider:o,apiKey:u(l("TOOLNET_LLM_API_KEY"),n.apiKey),baseUrl:u(l("TOOLNET_LLM_BASE_URL"),n.baseUrl,t.defaultBaseUrl),model:u(l("TOOLNET_LLM_MODEL"),n.model,t.defaultModel),accountId:u(l("TOOLNET_LLM_ACCOUNT_ID"),n.accountId)}}function ho(){let e=l("TOOLNET_EMBEDDING_PROVIDER");return e==="local"?"local":e&&x(e)?e:l("HF_TOKEN")||l("HF_EMBEDDING_MODEL")?"huggingface":"local"}function Do(){let e=ho();if(e==="local")return{provider:"local",model:u(l("TOOLNET_EMBEDDING_MODEL"),l("LOCAL_EMBEDDING_MODEL"))};let o=S(e),t,n,r,s;switch(e){case"huggingface":t=l("HF_TOKEN"),n=l("HF_INFERENCE_BASE_URL"),r=l("HF_EMBEDDING_MODEL");break;case"openai-compatible":t=l("OPENAI_API_KEY"),n=l("OPENAI_BASE_URL"),r=l("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":t=l("CLOUDFLARE_API_TOKEN"),n=l("CLOUDFLARE_AI_BASE_URL"),r=l("CLOUDFLARE_EMBEDDING_MODEL"),s=l("CLOUDFLARE_ACCOUNT_ID");break;default:t=$(e).apiKey,n=$(e).baseUrl,r=l(`${e.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let i=u(l("TOOLNET_EMBEDDING_ACCOUNT_ID"),s),c=u(l("TOOLNET_EMBEDDING_BASE_URL"),n,o.defaultBaseUrl),a=e==="cloudflare"&&!c&&i?`https://api.cloudflare.com/client/v4/accounts/${i}/ai/v1`:c;return{provider:e,apiKey:u(l("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:a,model:u(l("TOOLNET_EMBEDDING_MODEL"),r),accountId:i}}function bo(){let e=Ro(),o=Do();return{llm:e,embedding:o,legacy:{llm:!l("TOOLNET_LLM_PROVIDER")&&!!Te(),embedding:!l("TOOLNET_EMBEDDING_PROVIDER")&&!!(l("HF_TOKEN")||l("HF_EMBEDDING_MODEL"))}}}function ye(e=Ae()){let o=bo().llm;if(e===o.provider)return{id:e,apiKey:o.apiKey,baseUrl:o.baseUrl,model:o.model,accountId:o.accountId};let t=$(e);return{id:e,apiKey:t.apiKey,baseUrl:t.baseUrl,model:t.model,accountId:t.accountId}}var oe=class extends Error{status;constructor(o,t){super(o),this.name="AiHttpError",this.status=t}};async function R(e,o,t=3e4){let n=new AbortController,r=setTimeout(()=>n.abort(),t);r.unref?.();try{let s=await fetch(e,{...o,signal:n.signal}),i=await s.text();if(!s.ok){let c=i;try{let a=JSON.parse(i);c=a.error?.message??a.message??i}catch{}throw new oe(c||`HTTP ${s.status}`,s.status)}return i.trim()?JSON.parse(i):{}}finally{clearTimeout(r)}}function Y(e,o){return`${e.replace(/\/+$/,"")}/${o.replace(/^\/+/,"")}`}var v=class{constructor(o){this.config=o}config;id="cloudflare";model(){let o=this.config.model?.trim();if(!o)throw new Error("cloudflare: MODEL is not configured");return o}async generate(o){let t=this.config.accountId?.trim(),n=this.config.apiKey?.trim();if(!t)throw new Error("cloudflare: ACCOUNT ID is not configured");if(!n)throw new Error("cloudflare: API TOKEN is not configured");let r=this.model(),i=`${(this.config.baseUrl?.trim()||`https://api.cloudflare.com/client/v4/accounts/${t}/ai/run`).replace(/\/+$/,"")}/${r}`,c=await R(i,{method:"POST",headers:{authorization:`Bearer ${n}`,"content-type":"application/json",...this.config.headers},body:JSON.stringify({messages:o.messages,temperature:o.temperature,max_tokens:o.maxTokens})}),a=c.result?.response?.trim();if(!a)throw new Error(c.errors?.[0]?.message??"cloudflare: empty model response");return{text:a,provider:"cloudflare",model:r}}async healthCheck(){let o=Date.now();try{return{ok:!0,provider:"cloudflare",model:(await this.generate({messages:[{role:"user",content:"Reply exactly: OK"}],temperature:0,maxTokens:8})).model,message:"Provider reachable",latencyMs:Date.now()-o}}catch(t){return{ok:!1,provider:"cloudflare",model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-o}}}};var G=class{constructor(o){this.config=o}config;id="gemini";model(){let o=this.config.model?.trim();if(!o)throw new Error("gemini: MODEL is not configured");return o.replace(/^models\//,"")}async generate(o){let t=this.config.apiKey?.trim();if(!t)throw new Error("gemini: API KEY is not configured");let n=this.config.baseUrl?.trim()||"https://generativelanguage.googleapis.com/v1beta",r=this.model(),s=o.messages.filter(d=>d.role==="system"),i=o.messages.filter(d=>d.role!=="system").map(d=>({role:d.role==="assistant"?"model":"user",parts:[{text:d.content}]})),c=`${Y(n,`models/${encodeURIComponent(r)}:generateContent`)}?key=${encodeURIComponent(t)}`,a=await R(c,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...s.length?{systemInstruction:{parts:[{text:s.map(d=>d.content).join(`
2
2
 
3
- `)}]}}:{},contents:s,generationConfig:{temperature:o.temperature,maxOutputTokens:o.maxTokens}})}),g=l.candidates?.[0]?.content?.parts?.map(E=>E.text??"").join("").trim();if(!g)throw new Error("gemini: empty model response");return{text:g,provider:"gemini",model:r,usage:l.usageMetadata?{inputTokens:l.usageMetadata.promptTokenCount,outputTokens:l.usageMetadata.candidatesTokenCount,totalTokens:l.usageMetadata.totalTokenCount}:void 0}}async healthCheck(){let o=Date.now();try{return{ok:!0,provider:"gemini",model:(await this.generate({messages:[{role:"user",content:"Reply exactly: OK"}],temperature:0,maxTokens:8})).model,message:"Provider reachable",latencyMs:Date.now()-o}}catch(t){return{ok:!1,provider:"gemini",model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-o}}}};var $=class{constructor(o){this.config=o;this.id=o.id}config;id;baseUrl(){let o=this.config.baseUrl?.trim();if(!o)throw new Error(`${this.id}: BASE URL is not configured`);return o}model(){let o=this.config.model?.trim();if(!o)throw new Error(`${this.id}: MODEL is not configured`);return o}headers(){let o={"content-type":"application/json",...this.config.headers};return this.config.apiKey&&(o.authorization=`Bearer ${this.config.apiKey}`),o}async generate(o){let t=this.model(),n=await y(w(this.baseUrl(),"chat/completions"),{method:"POST",headers:this.headers(),body:JSON.stringify({model:t,messages:o.messages,temperature:o.temperature,max_tokens:o.maxTokens,...this.id==="alibaba"?{enable_thinking:!1}:{}})}),r=n.choices?.[0]?.message?.content?.trim();if(!r)throw new Error(`${this.id}: empty model response`);return{text:r,provider:this.id,model:t,usage:n.usage?{inputTokens:n.usage.prompt_tokens,outputTokens:n.usage.completion_tokens,totalTokens:n.usage.total_tokens}:void 0}}async healthCheck(){let o=Date.now();try{let t=await this.generate({messages:[{role:"user",content:"Reply exactly: OK"}],temperature:0,maxTokens:8});return{ok:!0,provider:this.id,model:t.model,message:"Provider reachable",latencyMs:Date.now()-o}}catch(t){return{ok:!1,provider:this.id,model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-o}}}};function _e(e=Ee()){switch(S(e.id).transport){case"gemini":return new Y(e);case"cloudflare":return new k(e);default:return new $(e)}}import{existsSync as z}from"node:fs";import{homedir as Q}from"node:os";import{join as Z}from"node:path";import{spawnSync as $o}from"node:child_process";import{existsSync as Qe,mkdirSync as Ze,readFileSync as eo,writeFileSync as oo}from"node:fs";import{homedir as to}from"node:os";import{dirname as no,join as ro}from"node:path";function io(e){return`'${e.replace(/'/g,"'\\''")}'`}function Oe(e={}){let o=e.hooksFile??ro(to(),".gemini","config","hooks.json");Ze(no(o),{recursive:!0});let t={};if(Qe(o))try{t=JSON.parse(eo(o,"utf8"))}catch(i){throw new Error(`Invalid existing Agy hooks.json: ${i instanceof Error?i.message:String(i)}`)}let n=e.binary??"toolnet-memory",r=`${io(n)} session:agy-hook`;return t["toolnet-memory"]={enabled:!0,PreToolUse:[{matcher:"view_file|list_dir|find_by_name|grep_search|run_command",hooks:[{type:"command",command:`${r} pre-tool`,timeout:5}]}],PreInvocation:[{type:"command",command:`${r} pre`,timeout:15}],PostInvocation:[{type:"command",command:`${r} post`,timeout:15}],Stop:[{type:"command",command:`${r} stop`,timeout:30}]},oo(o,JSON.stringify(t,null,2)+`
4
- `,{encoding:"utf8",mode:384}),o}import{existsSync as so,mkdirSync as co,readFileSync as ao,renameSync as lo,writeFileSync as go}from"node:fs";import{homedir as Eo}from"node:os";import{dirname as _o,join as Oo}from"node:path";function D(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function fo(e,o){co(_o(e),{recursive:!0});let t=`${e}.tmp-${process.pid}-${Date.now()}`;go(t,`${JSON.stringify(o,null,2)}
5
- `,{encoding:"utf8",mode:384}),lo(t,e)}function fe(e){if(!so(e))return{};let o=ao(e,"utf8").trim();if(!o)return{};let t;try{t=JSON.parse(o)}catch(n){throw new Error(`Invalid existing Agy MCP config: ${n instanceof Error?n.message:String(n)}`)}if(!D(t))throw new Error("Invalid existing Agy MCP config: root must be a JSON object.");return t}function me(e,o){return D(e)?e.command===o&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp":!1}function ue(e={}){let o=e.configFile??Oo(Eo(),".gemini","config","mcp_config.json"),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=e.serverName??"toolnet-memory",r=fe(o),i=r.mcpServers;if(i!==void 0&&!D(i))throw new Error("Invalid existing Agy MCP config: mcpServers must be an object.");let s=D(i)?{...i}:{},a=s[n];if(me(a,t))return{installed:!0,changed:!1,configFile:o,serverName:n,command:t,args:["mcp"]};s[n]={command:t,args:["mcp"]};let l={...r,mcpServers:s};fo(o,l);let E=fe(o).mcpServers;if(!D(E)||!me(E[n],t))throw new Error("Agy MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:o,serverName:n,command:t,args:["mcp"]}}import{existsSync as uo,mkdirSync as Te,readFileSync as Lo,writeFileSync as Ae}from"node:fs";import{homedir as J}from"node:os";import{join as F}from"node:path";var mo="memory_agent_ask";function Le(){return`
3
+ `)}]}}:{},contents:i,generationConfig:{temperature:o.temperature,maxOutputTokens:o.maxTokens}})}),g=a.candidates?.[0]?.content?.parts?.map(d=>d.text??"").join("").trim();if(!g)throw new Error("gemini: empty model response");return{text:g,provider:"gemini",model:r,usage:a.usageMetadata?{inputTokens:a.usageMetadata.promptTokenCount,outputTokens:a.usageMetadata.candidatesTokenCount,totalTokens:a.usageMetadata.totalTokenCount}:void 0}}async healthCheck(){let o=Date.now();try{return{ok:!0,provider:"gemini",model:(await this.generate({messages:[{role:"user",content:"Reply exactly: OK"}],temperature:0,maxTokens:8})).model,message:"Provider reachable",latencyMs:Date.now()-o}}catch(t){return{ok:!1,provider:"gemini",model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-o}}}};var j=class{constructor(o){this.config=o;this.id=o.id}config;id;baseUrl(){let o=this.config.baseUrl?.trim();if(!o)throw new Error(`${this.id}: BASE URL is not configured`);return o}model(){let o=this.config.model?.trim();if(!o)throw new Error(`${this.id}: MODEL is not configured`);return o}headers(){let o={"content-type":"application/json",...this.config.headers};return this.config.apiKey&&(o.authorization=`Bearer ${this.config.apiKey}`),o}async generate(o){let t=this.model(),n=await R(Y(this.baseUrl(),"chat/completions"),{method:"POST",headers:this.headers(),body:JSON.stringify({model:t,messages:o.messages,temperature:o.temperature,max_tokens:o.maxTokens,...this.id==="alibaba"?{enable_thinking:!1}:{}})}),r=n.choices?.[0]?.message?.content?.trim();if(!r)throw new Error(`${this.id}: empty model response`);return{text:r,provider:this.id,model:t,usage:n.usage?{inputTokens:n.usage.prompt_tokens,outputTokens:n.usage.completion_tokens,totalTokens:n.usage.total_tokens}:void 0}}async healthCheck(){let o=Date.now();try{let t=await this.generate({messages:[{role:"user",content:"Reply exactly: OK"}],temperature:0,maxTokens:8});return{ok:!0,provider:this.id,model:t.model,message:"Provider reachable",latencyMs:Date.now()-o}}catch(t){return{ok:!1,provider:this.id,model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-o}}}};function Me(e=ye()){switch(S(e.id).transport){case"gemini":return new G(e);case"cloudflare":return new v(e);default:return new j(e)}}import{existsSync as Uo}from"node:fs";import{homedir as Ko}from"node:os";import{join as ko}from"node:path";import{spawnSync as Bo}from"node:child_process";import{homedir as Po}from"node:os";import{join as h}from"node:path";function Ie(e={}){return h(e.home??Po(),".gemini")}function te(e={}){return h(Ie(e),"config")}function H(e={}){return h(te(e),"mcp_config.json")}function q(e={}){return h(te(e),"hooks.json")}function Ne(e={}){return h(Ie(e),"antigravity-cli")}function Ce(e="toolnet-memory",o={}){return h(Ne(o),"plugins",e)}function Se(e={}){return[Ne(e),te(e)]}import{homedir as wo}from"node:os";import{join as P}from"node:path";function M(e={}){let o=e.xdgConfigHome??process.env.XDG_CONFIG_HOME?.trim();return o?P(o,"opencode"):P(e.home??wo(),".config","opencode")}function Re(e={}){return P(M(e),"opencode.json")}function he(e={}){return P(M(e),"plugins")}function De(e={}){return P(M(e),"AGENTS.md")}import{homedir as be}from"node:os";import{join as ne}from"node:path";function re(e={}){return ne(e.home??be(),".claude")}function Pe(e={}){return ne(re(e),"settings.json")}function we(e={}){return ne(e.home??be(),".claude.json")}function Fo(e){return Bo("sh",["-lc",`command -v ${JSON.stringify(e)} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}function V(e){let o=e.commandExists(e.command),t=e.configPaths.filter(s=>Uo(s)),n=t.length>0,r=[];o&&r.push(`command:${e.command}`);for(let s of t)r.push(`config:${s}`);return{agent:e.agent,detected:o||n,commandDetected:o,configDetected:n,evidence:r}}function Ue(e={}){let o=e.home??Ko(),t=e.commandExists??Fo,n=e.codexHome??process.env.CODEX_HOME??ko(o,".codex");return[V({agent:"agy",command:"agy",commandExists:t,configPaths:Se({home:o})}),V({agent:"opencode",command:"opencode",commandExists:t,configPaths:[M({home:o,xdgConfigHome:e.xdgConfigHome})]}),V({agent:"claude",command:"claude",commandExists:t,configPaths:[re({home:o})]}),V({agent:"codex",command:"codex",commandExists:t,configPaths:[n]})]}import{existsSync as W,mkdirSync as $e,readFileSync as Ye,renameSync as et,writeFileSync as ot}from"node:fs";import{dirname as tt,join as J}from"node:path";import{existsSync as xo,mkdirSync as $o,readFileSync as Yo,renameSync as vo,rmSync as Go,writeFileSync as jo}from"node:fs";import{dirname as Ho}from"node:path";function qo(e){return`'${e.replace(/'/g,"'\\''")}'`}function Ke(e={}){let o=e.hooksFile??q();$o(Ho(o),{recursive:!0,mode:448});let t={};if(xo(o)){let i;try{i=JSON.parse(Yo(o,"utf8"))}catch(c){throw new Error(`Invalid existing Agy hooks.json: ${c instanceof Error?c.message:String(c)}`)}if(typeof i!="object"||i===null||Array.isArray(i))throw new Error("Invalid existing Agy hooks.json: root must be a JSON object.");t=i}let n=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=`${qo(n)} session:agy-hook`;t["toolnet-memory"]={enabled:!0,PreToolUse:[{matcher:"view_file|list_dir|find_by_name|grep_search|run_command",hooks:[{type:"command",command:`${r} pre-tool`,timeout:5}]}],PreInvocation:[{type:"command",command:`${r} pre`,timeout:15}],PostInvocation:[{type:"command",command:`${r} post`,timeout:15}],Stop:[{type:"command",command:`${r} stop`,timeout:30}]};let s=`${o}.tmp-${process.pid}-${Date.now()}`;try{jo(s,JSON.stringify(t,null,2)+`
4
+ `,{encoding:"utf8",mode:384}),vo(s,o)}finally{Go(s,{force:!0})}return o}import{existsSync as Vo,mkdirSync as Jo,readFileSync as Wo,renameSync as Xo,writeFileSync as zo}from"node:fs";import{dirname as Qo}from"node:path";function w(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Zo(e,o){Jo(Qo(e),{recursive:!0,mode:448});let t=`${e}.tmp-${process.pid}-${Date.now()}`;zo(t,`${JSON.stringify(o,null,2)}
5
+ `,{encoding:"utf8",mode:384}),Xo(t,e)}function ke(e){if(!Vo(e))return{};let o=Wo(e,"utf8").trim();if(!o)return{};let t;try{t=JSON.parse(o)}catch(n){throw new Error(`Invalid existing Agy MCP config: ${n instanceof Error?n.message:String(n)}`)}if(!w(t))throw new Error("Invalid existing Agy MCP config: root must be a JSON object.");return t}function Be(e,o){return w(e)?e.command===o&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp":!1}function Fe(e={}){let o=e.configFile??H(),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=e.serverName??"toolnet-memory",r=ke(o),s=r.mcpServers;if(s!==void 0&&!w(s))throw new Error("Invalid existing Agy MCP config: mcpServers must be an object.");let i=w(s)?{...s}:{},c=i[n];if(Be(c,t))return{installed:!0,changed:!1,configFile:o,serverName:n,command:t,args:["mcp"]};i[n]={command:t,args:["mcp"]};let a={...r,mcpServers:i};Zo(o,a);let d=ke(o).mcpServers;if(!w(d)||!Be(d[n],t))throw new Error("Agy MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:o,serverName:n,command:t,args:["mcp"]}}var nt=`# ToolNet Memory Continuity
6
+
7
+ ToolNet Memory is the authoritative continuity layer for previous project work.
8
+
9
+ ## Resume / continue behavior
10
+
11
+ Whenever the user asks to continue, resume, finish, pick up, return to, or complete previous work:
12
+
13
+ 1. FIRST call the ToolNet Memory MCP tool \`memory_agent_ask\`.
14
+ 2. Use ToolNet's compact continuity result to determine:
15
+ - current task
16
+ - completed work
17
+ - current or last file
18
+ - TODOs
19
+ - blockers
20
+ - next action
21
+ 3. Only AFTER continuity is known may you inspect current source or git to verify repository truth.
22
+
23
+ ## Forbidden continuity recovery
24
+
25
+ Do NOT reconstruct previous work by reading, listing, searching, or shelling into:
26
+
27
+ - \`.toolnet/sessions/**\`
28
+ - \`state.json\`
29
+ - \`events.jsonl\`
30
+ - raw transcripts
31
+ - \`~/.gemini/antigravity-cli/brain/**\`
32
+ - Antigravity \`transcript.jsonl\`
33
+ - another coding agent's internal session history
34
+
35
+ Do NOT run Bash/cat/tail/grep against those locations to discover previous work.
36
+
37
+ Do NOT search the filesystem for the implementation or schema of \`memory_agent_ask\`.
38
+ Invoke the MCP tool directly.
39
+
40
+ For direct continuity facts, prefer \`mode="local"\`.
41
+ Use \`mode="ai"\` only when continuity is ambiguous or requires synthesis.
42
+
43
+ Current repository evidence overrides stale memory after ToolNet has restored the working context.
44
+
45
+ Do not ask the user to repeat context already available through ToolNet Memory.
46
+ `;function ve(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ie(e,o){$e(tt(e),{recursive:!0});let t=`${e}.tmp-${process.pid}-${Date.now()}`;ot(t,o,{encoding:"utf8",mode:384}),et(t,e)}function xe(e,o){W(e)&&Ye(e,"utf8")===o||ie(e,o)}function Ge(e){if(!W(e))return{};let o=Ye(e,"utf8").trim();if(!o)return{};let t;try{t=JSON.parse(o)}catch(n){throw new Error(`Invalid legacy Antigravity config ${e}: ${n instanceof Error?n.message:String(n)}`)}if(!ve(t))throw new Error(`Invalid legacy Antigravity config ${e}: root must be object`);return t}function rt(e,o){if(!W(e))return!1;let t=Ge(e);if(!ve(t.mcpServers)||!Object.prototype.hasOwnProperty.call(t.mcpServers,o))return!1;let n={...t.mcpServers};return delete n[o],ie(e,`${JSON.stringify({...t,mcpServers:n},null,2)}
47
+ `),!0}function it(e){if(!W(e))return!1;let o=Ge(e);if(!Object.prototype.hasOwnProperty.call(o,"toolnet-memory"))return!1;let t={...o};return delete t["toolnet-memory"],ie(e,`${JSON.stringify(t,null,2)}
48
+ `),!0}function je(e={}){let o=e.pluginName??"toolnet-memory",t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=e.pluginRoot??Ce(o),r=J(n,"plugin.json"),s=J(n,"mcp_config.json"),i=J(n,"hooks.json"),c=J(n,"rules","toolnet-memory-continuity.md");$e(n,{recursive:!0,mode:448}),xe(r,`${JSON.stringify({$schema:"https://antigravity.google/schemas/v1/plugin.json",name:o,description:"Persistent project continuity and memory for Antigravity coding sessions."},null,2)}
49
+ `),Fe({configFile:s,binary:t,serverName:"toolnet-memory"}),Ke({hooksFile:i,binary:t}),xe(c,`${nt.trim()}
50
+ `);let a=e.legacyMcpFile??H(),g=e.legacyHooksFile??q(),d=[];return a!==s&&rt(a,"toolnet-memory")&&d.push(a),g!==i&&it(g)&&d.push(g),{installed:!0,pluginRoot:n,files:[r,s,i,c],migratedLegacy:d}}import{existsSync as ct,mkdirSync as Ve,readFileSync as at,writeFileSync as Je}from"node:fs";import{join as lt}from"node:path";var st="memory_agent_ask";function He(){return`
6
51
  [TOOLNET MEMORY AGENT]
7
52
 
8
53
  Tool available:
9
- - ${mo}
54
+ - ${st}
10
55
 
11
56
  Use it automatically BEFORE guessing when:
12
57
 
@@ -53,7 +98,7 @@ Rules:
53
98
  - After receiving the ToolNet answer, continue the task
54
99
  instead of asking the user to repeat known context.
55
100
  - If ToolNet says information is not recorded, say so.
56
- `.trim()}var pe="<!-- TOOLNET_MEMORY_BOOTSTRAP_START -->",V="<!-- TOOLNET_MEMORY_BOOTSTRAP_END -->";function po(){let e=F(J(),".config","opencode","AGENTS.md");Te(F(J(),".config","opencode"),{recursive:!0});let o=`${pe}
101
+ `.trim()}var qe="<!-- TOOLNET_MEMORY_BOOTSTRAP_START -->",se="<!-- TOOLNET_MEMORY_BOOTSTRAP_END -->";function gt(){let e=De();Ve(M(),{recursive:!0});let o=`${qe}
57
102
  ## ToolNet Memory
58
103
 
59
104
  ToolNet Memory is available for projects that already contain a valid \`.toolnet/project.json\`.
@@ -69,12 +114,12 @@ Rules:
69
114
  7. Current repository evidence has priority over stale memory when they conflict.
70
115
 
71
116
 
72
- ${Le()}
117
+ ${He()}
73
118
 
74
- ${V}`,t=uo(e)?Lo(e,"utf8"):"",n=t.indexOf(pe),r=t.indexOf(V);return n>=0&&r>=n?t=t.slice(0,n)+o+t.slice(r+V.length):(t=t.trimEnd(),t&&(t+=`
119
+ ${se}`,t=ct(e)?at(e,"utf8"):"",n=t.indexOf(qe),r=t.indexOf(se);return n>=0&&r>=n?t=t.slice(0,n)+o+t.slice(r+se.length):(t=t.trimEnd(),t&&(t+=`
75
120
 
76
- `),t+=o),Ae(e,t.trimEnd()+`
77
- `,{encoding:"utf8",mode:384}),e}function Me(e={}){let o=e.directory??F(J(),".config","opencode","plugins");Te(o,{recursive:!0}),po();let t=F(o,"toolnet-memory.js"),n=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=`
121
+ `),t+=o),Je(e,t.trimEnd()+`
122
+ `,{encoding:"utf8",mode:384}),e}function We(e={}){let o=e.directory??he();Ve(o,{recursive:!0}),gt();let t=lt(o,"toolnet-memory.js"),n=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=`
78
123
  // Generated by ToolNet Memory.
79
124
  // OpenCode integration:
80
125
  // - project gated
@@ -702,18 +747,20 @@ export const ToolNetMemoryPlugin =
702
747
  },
703
748
  }
704
749
  }
705
- `;return Ae(t,r.trimStart(),{encoding:"utf8",mode:384}),t}import{existsSync as Ce,mkdirSync as To,readFileSync as Ao,renameSync as Mo,writeFileSync as No}from"node:fs";import{homedir as Io}from"node:os";import{dirname as Se,join as x}from"node:path";function h(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Co(){let e=process.env.XDG_CONFIG_HOME?.trim();return e?x(e,"opencode"):x(Io(),".config","opencode")}function So(){return x(Co(),"opencode.json")}function yo(e,o){To(Se(e),{recursive:!0});let t=`${e}.tmp-${process.pid}-${Date.now()}`;No(t,`${JSON.stringify(o,null,2)}
706
- `,{encoding:"utf8",mode:384}),Mo(t,e)}function Ne(e){if(!Ce(e))return{};let o=Ao(e,"utf8").trim();if(!o)return{};let t;try{t=JSON.parse(o)}catch(n){throw new Error(`Invalid existing OpenCode opencode.json: ${n instanceof Error?n.message:String(n)}`)}if(!h(t))throw new Error("Invalid existing OpenCode opencode.json: root must be a JSON object.");return t}function Ie(e,o){if(!h(e))return!1;let t=e.command;return e.type==="local"&&e.enabled!==!1&&Array.isArray(t)&&t.length===2&&t[0]===o&&t[1]==="mcp"}function ye(e={}){let o=e.configFile??So(),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=e.serverName??"toolnet-memory",r=x(Se(o),"opencode.jsonc"),i=Ce(r)?r:void 0,s=Ne(o),a=s.mcp;if(a!==void 0&&!h(a))throw new Error("Invalid existing OpenCode config: mcp must be an object.");let l=h(a)?{...a}:{},g=l[n];if(Ie(g,t))return{installed:!0,changed:!1,configFile:o,serverName:n,command:[t,"mcp"],preservedJsonc:i};l[n]={type:"local",command:[t,"mcp"],enabled:!0};let E={...s,mcp:l};yo(o,E);let u=Ne(o);if(!h(u.mcp)||!Ie(u.mcp[n],t))throw new Error("OpenCode MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:o,serverName:n,command:[t,"mcp"],preservedJsonc:i}}import{existsSync as Ro,mkdirSync as Re,readFileSync as Do,writeFileSync as De}from"node:fs";import{homedir as he}from"node:os";import{dirname as be,join as W}from"node:path";function ho(e){let o=[],t=/"((?:\\.|[^"\\])*)"|'([^']*)'/g,n;for(;n=t.exec(e);){let r=n[1]??n[2]??"";try{o.push(n[1]!==void 0?JSON.parse(`"${r}"`):r)}catch{o.push(r)}}return o}function Pe(e={}){let o=e.configFile??W(process.env.CODEX_HOME??W(he(),".codex"),"config.toml"),t=e.previousFile??W(he(),".config","toolnet-memory","codex-notify-previous.json");Re(be(o),{recursive:!0}),Re(be(t),{recursive:!0});let n=Ro(o)?Do(o,"utf8"):"",r=e.binary??"toolnet-memory",i=`notify = [${JSON.stringify(r)}, "session:codex-notify"]`,s=n.split(`
707
- `),a=s.findIndex(O=>/^\s*\[/.test(O));a<0&&(a=s.length);let l=-1,g=-1;for(let O=0;O<a;O+=1)if(/^\s*notify\s*=/.test(s[O])){if(l=O,g=O,s[O].includes("[")&&!s[O].includes("]"))for(;g+1<a&&(g+=1,!s[g].includes("]")););break}let E=[];if(l>=0){let O=s.slice(l,g+1).join(`
708
- `);E=ho(O),s.splice(l,g-l+1,i)}else a=s.findIndex(O=>/^\s*\[/.test(O)),a<0&&(a=s.length),s.splice(a,0,i);let u=E.length>=2&&E[E.length-1]==="session:codex-notify";return E.length>0&&!u&&De(t,JSON.stringify(E,null,2)+`
709
- `,{encoding:"utf8",mode:384}),n=s.join(`
750
+ `;return Je(t,r.trimStart(),{encoding:"utf8",mode:384}),t}import{existsSync as Qe,mkdirSync as dt,readFileSync as Et,renameSync as _t,writeFileSync as mt}from"node:fs";import{dirname as Ze,join as ut}from"node:path";function D(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ft(e,o){dt(Ze(e),{recursive:!0});let t=`${e}.tmp-${process.pid}-${Date.now()}`;mt(t,`${JSON.stringify(o,null,2)}
751
+ `,{encoding:"utf8",mode:384}),_t(t,e)}function Xe(e){if(!Qe(e))return{};let o=Et(e,"utf8").trim();if(!o)return{};let t;try{t=JSON.parse(o)}catch(n){throw new Error(`Invalid existing OpenCode opencode.json: ${n instanceof Error?n.message:String(n)}`)}if(!D(t))throw new Error("Invalid existing OpenCode opencode.json: root must be a JSON object.");return t}function ze(e,o){if(!D(e))return!1;let t=e.command;return e.type==="local"&&e.enabled!==!1&&Array.isArray(t)&&t.length===2&&t[0]===o&&t[1]==="mcp"}function Ot(e,o){let t=e.mcpServers;if(!D(t)||!Object.prototype.hasOwnProperty.call(t,o))return{root:e,changed:!1};let n={...t};return delete n[o],{root:{...e,mcpServers:n},changed:!0}}function eo(e={}){let o=e.configFile??Re(),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=e.serverName??"toolnet-memory",r=ut(Ze(o),"opencode.jsonc"),s=Qe(r)?r:void 0,i=Xe(o),c=Ot(i,n),a=c.root,g=a.mcp;if(g!==void 0&&!D(g))throw new Error("Invalid existing OpenCode config: mcp must be an object.");let d=D(g)?{...g}:{},f=d[n];if(ze(f,t)&&!c.changed)return{installed:!0,changed:!1,configFile:o,serverName:n,command:[t,"mcp"],preservedJsonc:s};d[n]={type:"local",command:[t,"mcp"],enabled:!0};let _={...a,mcp:d};ft(o,_);let ee=Xe(o);if(!D(ee.mcp)||!ze(ee.mcp[n],t))throw new Error("OpenCode MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:o,serverName:n,command:[t,"mcp"],preservedJsonc:s}}import{existsSync as pt,mkdirSync as oo,readFileSync as Lt,writeFileSync as to}from"node:fs";import{homedir as no}from"node:os";import{dirname as ro,join as ce}from"node:path";function Tt(e){let o=[],t=/"((?:\\.|[^"\\])*)"|'([^']*)'/g,n;for(;n=t.exec(e);){let r=n[1]??n[2]??"";try{o.push(n[1]!==void 0?JSON.parse(`"${r}"`):r)}catch{o.push(r)}}return o}function io(e={}){let o=e.configFile??ce(process.env.CODEX_HOME??ce(no(),".codex"),"config.toml"),t=e.previousFile??ce(no(),".config","toolnet-memory","codex-notify-previous.json");oo(ro(o),{recursive:!0}),oo(ro(t),{recursive:!0});let n=pt(o)?Lt(o,"utf8"):"",r=e.binary??"toolnet-memory",s=`notify = [${JSON.stringify(r)}, "session:codex-notify"]`,i=n.split(`
752
+ `),c=i.findIndex(_=>/^\s*\[/.test(_));c<0&&(c=i.length);let a=-1,g=-1;for(let _=0;_<c;_+=1)if(/^\s*notify\s*=/.test(i[_])){if(a=_,g=_,i[_].includes("[")&&!i[_].includes("]"))for(;g+1<c&&(g+=1,!i[g].includes("]")););break}let d=[];if(a>=0){let _=i.slice(a,g+1).join(`
753
+ `);d=Tt(_),i.splice(a,g-a+1,s)}else c=i.findIndex(_=>/^\s*\[/.test(_)),c<0&&(c=i.length),i.splice(c,0,s);let f=d.length>=2&&d[d.length-1]==="session:codex-notify";return d.length>0&&!f&&to(t,JSON.stringify(d,null,2)+`
754
+ `,{encoding:"utf8",mode:384}),n=i.join(`
710
755
  `),n.endsWith(`
711
756
  `)||(n+=`
712
- `),De(o,n,{encoding:"utf8",mode:384}),{configFile:o,previousFile:t,preservedPrevious:E.length>0&&!u}}import{existsSync as bo,mkdirSync as Po,readFileSync as Uo,writeFileSync as Ko}from"node:fs";import{homedir as Bo}from"node:os";import{dirname as wo,join as Ue}from"node:path";function ko(e){return`'${e.replace(/'/g,"'\\''")}'`}function Ke(e={}){let o=e.hooksFile??Ue(process.env.CODEX_HOME??Ue(Bo(),".codex"),"hooks.json");Po(wo(o),{recursive:!0});let t={};if(bo(o))try{t=JSON.parse(Uo(o,"utf8"))}catch(a){throw new Error(`Invalid existing Codex hooks.json: ${a instanceof Error?a.message:String(a)}`)}let n=t.hooks&&typeof t.hooks=="object"&&!Array.isArray(t.hooks)?t.hooks:{};t.hooks=n;let i=(Array.isArray(n.SessionStart)?n.SessionStart:[]).filter(a=>{try{return!JSON.stringify(a).includes("session:codex-context")}catch{return!0}}),s=e.binary??"toolnet-memory";return i.push({matcher:"startup|resume|clear|compact",hooks:[{type:"command",command:`${ko(s)} session:codex-context`,timeout:15,additionalContextLimit:1e3,statusMessage:"Loading ToolNet project continuity"}]}),n.SessionStart=i,Ko(o,JSON.stringify(t,null,2)+`
713
- `,{encoding:"utf8",mode:384}),o}import{spawnSync as Yo}from"node:child_process";function X(e,o){return Yo(e,o,{encoding:"utf8",stdio:["ignore","pipe","pipe"]})}function Be(e,o){let t=X(e,["mcp","get",o,"--json"]);if(t.status!==0||!t.stdout)return null;try{return JSON.parse(t.stdout)}catch{return null}}function we(e,o){return e.enabled!==!1&&e.transport?.type==="stdio"&&e.transport?.command===o&&Array.isArray(e.transport?.args)&&e.transport?.args.length===1&&e.transport.args[0]==="mcp"}function ke(e={}){let o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=e.codexBinary??"codex",n=e.serverName??"toolnet-memory",r=Be(t,n);if(r&&we(r,o))return{installed:!0,changed:!1,serverName:n,command:o,args:["mcp"]};if(r){let a=X(t,["mcp","remove",n]);if(a.status!==0)return{installed:!1,changed:!1,serverName:n,command:o,args:["mcp"],error:(a.stderr||a.stdout||"Unable to remove old ToolNet MCP configuration.").trim()}}let i=X(t,["mcp","add",n,"--",o,"mcp"]);if(i.status!==0)return{installed:!1,changed:!1,serverName:n,command:o,args:["mcp"],error:(i.stderr||i.stdout||"Unable to register ToolNet MCP.").trim()};let s=Be(t,n);return!s||!we(s,o)?{installed:!1,changed:!0,serverName:n,command:o,args:["mcp"],error:"Codex accepted MCP registration but verification did not match expected ToolNet command."}:{installed:!0,changed:!0,serverName:n,command:o,args:["mcp"]}}function ee(e){return $o("sh",["-lc",`command -v ${JSON.stringify(e)} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}function Fo(){return ee("agy")||z(Z(Q(),".gemini"))}function xo(){return ee("opencode")||z(Z(Q(),".config","opencode"))}function Go(){return ee("codex")||z(process.env.CODEX_HOME??Z(Q(),".codex"))}function oe(e={}){let o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=[];if(!(e.force===!0||Fo()))t.push({agent:"agy",detected:!1,installed:!1,targets:[]});else try{let r=Oe({binary:o}),i=ue({binary:o});t.push({agent:"agy",detected:!0,installed:!0,targets:[r,i.configFile]})}catch(r){t.push({agent:"agy",detected:!0,installed:!1,targets:[],error:r instanceof Error?r.message:String(r)})}if(!(e.force===!0||xo()))t.push({agent:"opencode",detected:!1,installed:!1,targets:[]});else try{let r=Me({binary:o}),i=ye({binary:o});t.push({agent:"opencode",detected:!0,installed:!0,targets:[r,i.configFile,`mcp:${i.serverName}`]})}catch(r){t.push({agent:"opencode",detected:!0,installed:!1,targets:[],error:r instanceof Error?r.message:String(r)})}if(!(e.force===!0||Go()))t.push({agent:"codex",detected:!1,installed:!1,targets:[]});else try{let r=Pe({binary:o}),i=Ke({binary:o}),s=ke({binary:o});if(!s.installed)throw new Error(s.error??"Codex MCP registration failed");let a=[r.configFile,i,`mcp:${s.serverName}`];r.preservedPrevious&&a.push(r.previousFile),t.push({agent:"codex",detected:!0,installed:!0,targets:a})}catch(r){t.push({agent:"codex",detected:!0,installed:!1,targets:[],error:r instanceof Error?r.message:String(r)})}return t}function qo(e){console.log(""),console.log("ToolNet Memory AI Integrations"),console.log("=============================="),console.log("");for(let o of e){let t=o.agent==="agy"?"Agy / Antigravity":o.agent==="opencode"?"OpenCode":"Codex";if(!o.detected){console.log(`- ${t}: not detected`);continue}if(o.installed){console.log(`\u2713 ${t}: automatic memory enabled`);continue}console.log(`\u2717 ${t}: integration failed`),o.error&&console.log(` ${o.error}`)}console.log("")}async function Ho(){let e=process.argv.slice(2),o=e.includes("--all"),t=e.includes("--json"),n=oe({force:o});if(t){console.log(JSON.stringify(n,null,2));return}qo(n)}var jo=process.argv[1]&&(process.argv[1].endsWith("auto-integrate.js")||process.argv[1].endsWith("auto-integrate.ts"));jo&&Ho().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});var te=P.join(ne.homedir(),".config","toolnet-memory"),L=P.join(te,".env"),Wo=new Set(["MEMORY_STORAGE_PROVIDER","R2_ACCOUNT_ID","R2_BUCKET","R2_ACCESS_KEY_ID","R2_SECRET_ACCESS_KEY","S3_ENDPOINT","S3_REGION","S3_BUCKET","S3_ACCESS_KEY_ID","S3_SECRET_ACCESS_KEY","S3_FORCE_PATH_STYLE","HF_NAMESPACE","HF_BUCKET","HF_S3_ACCESS_KEY_ID","HF_S3_SECRET_ACCESS_KEY","HF_URL","HF_TOKEN","HF_EMBEDDING_MODEL","TOOLNET_LLM_PROVIDER","TOOLNET_LLM_API_KEY","TOOLNET_LLM_BASE_URL","TOOLNET_LLM_MODEL","TOOLNET_LLM_FALLBACK_1_PROVIDER","TOOLNET_LLM_FALLBACK_1_API_KEY","TOOLNET_LLM_FALLBACK_1_BASE_URL","TOOLNET_LLM_FALLBACK_1_MODEL","TOOLNET_LLM_FALLBACK_1_ACCOUNT_ID","TOOLNET_LLM_FALLBACK_2_PROVIDER","TOOLNET_LLM_FALLBACK_2_API_KEY","TOOLNET_LLM_FALLBACK_2_BASE_URL","TOOLNET_LLM_FALLBACK_2_MODEL","TOOLNET_LLM_FALLBACK_2_ACCOUNT_ID","TOOLNET_LLM_FALLBACK_COOLDOWN_MS","TOOLNET_LLM_MAX_RETRIES","TOOLNET_LLM_ACCOUNT_ID","TOOLNET_EMBEDDING_PROVIDER","TOOLNET_EMBEDDING_API_KEY","TOOLNET_EMBEDDING_BASE_URL","TOOLNET_EMBEDDING_MODEL","TOOLNET_EMBEDDING_ACCOUNT_ID","MEMORY_LOCAL_STORAGE_PATH","MEMORY_LOCAL_CACHE_MB","MEMORY_AUTO_CAPTURE","MEMORY_AUTO_RETRIEVE","MEMORY_AUTO_SUMMARIZE","MEMORY_AUTO_SYNC","MEMORY_MAX_CANDIDATES","MEMORY_RERANK_TOP","MEMORY_FINAL_CONTEXT","MEMORY_TOKEN_BUDGET","TOOLNET_SESSION_LEARNING","TOOLNET_WORK_CONTINUITY","TOOLNET_SEMANTIC_CONTINUITY","TOOLNET_SMART_HANDOFF"]);function Xo(e){let o=new Map;for(let t of e.split(/\r?\n/)){let n=t.trim();if(!n||n.startsWith("#"))continue;let r=n.indexOf("=");if(r===-1)continue;let i=n.slice(0,r).trim(),s=n.slice(r+1).trim();i&&o.set(i,s)}return o}function I(e){let o=e.get("MEMORY_STORAGE_PROVIDER")?.trim();return o==="r2"||o==="s3"||o==="local"||o==="huggingface"?o:e.get("R2_ACCOUNT_ID")&&e.get("R2_BUCKET")?"r2":e.get("S3_BUCKET")?"s3":e.get("HF_BUCKET")&&e.get("HF_S3_ACCESS_KEY_ID")?"huggingface":e.get("MEMORY_LOCAL_STORAGE_PATH")?"local":"r2"}function U(e){switch(e){case"r2":return"Cloudflare R2";case"s3":return"S3 / S3-compatible";case"huggingface":return"Hugging Face S3";case"local":return"Local";default:return e}}function xe(e){switch(e){case"r2":return["R2_ACCOUNT_ID","R2_BUCKET","R2_ACCESS_KEY_ID","R2_SECRET_ACCESS_KEY"];case"s3":return["S3_BUCKET","S3_ACCESS_KEY_ID","S3_SECRET_ACCESS_KEY"];case"huggingface":return["HF_BUCKET","HF_S3_ACCESS_KEY_ID","HF_S3_SECRET_ACCESS_KEY"];case"local":return[];default:return[]}}function Ge(e){let o=I(e);return o==="local"?!0:xe(o).every(t=>!!e.get(t)?.trim())}function re(e){return e?e.length<=8?"configured":`${e.slice(0,4)}\u2022\u2022\u2022\u2022${e.slice(-3)}`:"not configured"}function zo(e){let t=["# ==========================================================","# TOOLNET MEMORY","# Generated by: toolnet-memory setup","# Do not commit this file.","# ==========================================================","",`MEMORY_STORAGE_PROVIDER=${I(e)}`,"","# ----------------------------------------------------------","# Cloudflare R2","# ----------------------------------------------------------",`R2_ACCOUNT_ID=${e.get("R2_ACCOUNT_ID")??""}`,`R2_BUCKET=${e.get("R2_BUCKET")??"toolnet-memory"}`,`R2_ACCESS_KEY_ID=${e.get("R2_ACCESS_KEY_ID")??""}`,`R2_SECRET_ACCESS_KEY=${e.get("R2_SECRET_ACCESS_KEY")??""}`,"","# ----------------------------------------------------------","# Generic S3 / S3-compatible","# ----------------------------------------------------------",`S3_ENDPOINT=${e.get("S3_ENDPOINT")??""}`,`S3_REGION=${e.get("S3_REGION")??"us-east-1"}`,`S3_BUCKET=${e.get("S3_BUCKET")??"toolnet-memory"}`,`S3_ACCESS_KEY_ID=${e.get("S3_ACCESS_KEY_ID")??""}`,`S3_SECRET_ACCESS_KEY=${e.get("S3_SECRET_ACCESS_KEY")??""}`,`S3_FORCE_PATH_STYLE=${e.get("S3_FORCE_PATH_STYLE")??"false"}`,"","# ----------------------------------------------------------","# Hugging Face S3","# ----------------------------------------------------------",`HF_NAMESPACE=${e.get("HF_NAMESPACE")??""}`,`HF_BUCKET=${e.get("HF_BUCKET")??"toolnet-memory"}`,`HF_S3_ACCESS_KEY_ID=${e.get("HF_S3_ACCESS_KEY_ID")??""}`,`HF_S3_SECRET_ACCESS_KEY=${e.get("HF_S3_SECRET_ACCESS_KEY")??""}`,`HF_URL=${e.get("HF_URL")??""}`,"","# ----------------------------------------------------------","# AI / LLM - canonical ToolNet configuration","# ----------------------------------------------------------",`TOOLNET_LLM_PROVIDER=${e.get("TOOLNET_LLM_PROVIDER")??""}`,`TOOLNET_LLM_API_KEY=${e.get("TOOLNET_LLM_API_KEY")??""}`,`TOOLNET_LLM_BASE_URL=${e.get("TOOLNET_LLM_BASE_URL")??""}`,`TOOLNET_LLM_MODEL=${e.get("TOOLNET_LLM_MODEL")??""}`,`TOOLNET_LLM_ACCOUNT_ID=${e.get("TOOLNET_LLM_ACCOUNT_ID")??""}`,"","# ----------------------------------------------------------","# LLM fallback chain","# ----------------------------------------------------------",`TOOLNET_LLM_FALLBACK_1_PROVIDER=${e.get("TOOLNET_LLM_FALLBACK_1_PROVIDER")??""}`,`TOOLNET_LLM_FALLBACK_1_API_KEY=${e.get("TOOLNET_LLM_FALLBACK_1_API_KEY")??""}`,`TOOLNET_LLM_FALLBACK_1_BASE_URL=${e.get("TOOLNET_LLM_FALLBACK_1_BASE_URL")??""}`,`TOOLNET_LLM_FALLBACK_1_MODEL=${e.get("TOOLNET_LLM_FALLBACK_1_MODEL")??""}`,`TOOLNET_LLM_FALLBACK_1_ACCOUNT_ID=${e.get("TOOLNET_LLM_FALLBACK_1_ACCOUNT_ID")??""}`,`TOOLNET_LLM_FALLBACK_2_PROVIDER=${e.get("TOOLNET_LLM_FALLBACK_2_PROVIDER")??""}`,`TOOLNET_LLM_FALLBACK_2_API_KEY=${e.get("TOOLNET_LLM_FALLBACK_2_API_KEY")??""}`,`TOOLNET_LLM_FALLBACK_2_BASE_URL=${e.get("TOOLNET_LLM_FALLBACK_2_BASE_URL")??""}`,`TOOLNET_LLM_FALLBACK_2_MODEL=${e.get("TOOLNET_LLM_FALLBACK_2_MODEL")??""}`,`TOOLNET_LLM_FALLBACK_2_ACCOUNT_ID=${e.get("TOOLNET_LLM_FALLBACK_2_ACCOUNT_ID")??""}`,`TOOLNET_LLM_FALLBACK_COOLDOWN_MS=${e.get("TOOLNET_LLM_FALLBACK_COOLDOWN_MS")??"60000"}`,`TOOLNET_LLM_MAX_RETRIES=${e.get("TOOLNET_LLM_MAX_RETRIES")??"1"}`,"","# ----------------------------------------------------------","# Embedding - canonical ToolNet configuration","# ----------------------------------------------------------",`TOOLNET_EMBEDDING_PROVIDER=${e.get("TOOLNET_EMBEDDING_PROVIDER")??""}`,`TOOLNET_EMBEDDING_API_KEY=${e.get("TOOLNET_EMBEDDING_API_KEY")??""}`,`TOOLNET_EMBEDDING_BASE_URL=${e.get("TOOLNET_EMBEDDING_BASE_URL")??""}`,`TOOLNET_EMBEDDING_MODEL=${e.get("TOOLNET_EMBEDDING_MODEL")??""}`,`TOOLNET_EMBEDDING_ACCOUNT_ID=${e.get("TOOLNET_EMBEDDING_ACCOUNT_ID")??""}`,"","# ----------------------------------------------------------","# Embedding - legacy/current compatibility","# ----------------------------------------------------------",`HF_TOKEN=${e.get("HF_TOKEN")??""}`,`HF_EMBEDDING_MODEL=${e.get("HF_EMBEDDING_MODEL")??"sentence-transformers/all-MiniLM-L6-v2"}`,"","# ----------------------------------------------------------","# Local storage/cache","# ----------------------------------------------------------",`MEMORY_LOCAL_STORAGE_PATH=${e.get("MEMORY_LOCAL_STORAGE_PATH")??""}`,`MEMORY_LOCAL_CACHE_MB=${e.get("MEMORY_LOCAL_CACHE_MB")??"200"}`,"","# ----------------------------------------------------------","# Automation","# ----------------------------------------------------------",`MEMORY_AUTO_CAPTURE=${e.get("MEMORY_AUTO_CAPTURE")??"true"}`,`MEMORY_AUTO_RETRIEVE=${e.get("MEMORY_AUTO_RETRIEVE")??"true"}`,`MEMORY_AUTO_SUMMARIZE=${e.get("MEMORY_AUTO_SUMMARIZE")??"true"}`,`MEMORY_AUTO_SYNC=${e.get("MEMORY_AUTO_SYNC")??"true"}`,"","# ----------------------------------------------------------","# Retrieval","# ----------------------------------------------------------",`MEMORY_MAX_CANDIDATES=${e.get("MEMORY_MAX_CANDIDATES")??"50"}`,`MEMORY_RERANK_TOP=${e.get("MEMORY_RERANK_TOP")??"10"}`,`MEMORY_FINAL_CONTEXT=${e.get("MEMORY_FINAL_CONTEXT")??"5"}`,`MEMORY_TOKEN_BUDGET=${e.get("MEMORY_TOKEN_BUDGET")??"2000"}`,"","# ----------------------------------------------------------","# Automatic Session Memory","# ----------------------------------------------------------",`TOOLNET_SESSION_LEARNING=${e.get("TOOLNET_SESSION_LEARNING")??"1"}`,`TOOLNET_WORK_CONTINUITY=${e.get("TOOLNET_WORK_CONTINUITY")??"1"}`,`TOOLNET_SEMANTIC_CONTINUITY=${e.get("TOOLNET_SEMANTIC_CONTINUITY")??"1"}`,`TOOLNET_SMART_HANDOFF=${e.get("TOOLNET_SMART_HANDOFF")??"1"}`],n=[...e.entries()].filter(([r])=>!Wo.has(r));if(n.length>0){t.push("","# ----------------------------------------------------------","# Preserved settings","# ----------------------------------------------------------");for(let[r,i]of n)t.push(`${r}=${i}`)}return`${t.join(`
757
+ `),to(o,n,{encoding:"utf8",mode:384}),{configFile:o,previousFile:t,preservedPrevious:d.length>0&&!f}}import{existsSync as At,mkdirSync as yt,readFileSync as Mt,writeFileSync as It}from"node:fs";import{homedir as Nt}from"node:os";import{dirname as Ct,join as so}from"node:path";function St(e){return`'${e.replace(/'/g,"'\\''")}'`}function co(e={}){let o=e.hooksFile??so(process.env.CODEX_HOME??so(Nt(),".codex"),"hooks.json");yt(Ct(o),{recursive:!0});let t={};if(At(o))try{t=JSON.parse(Mt(o,"utf8"))}catch(c){throw new Error(`Invalid existing Codex hooks.json: ${c instanceof Error?c.message:String(c)}`)}let n=t.hooks&&typeof t.hooks=="object"&&!Array.isArray(t.hooks)?t.hooks:{};t.hooks=n;let s=(Array.isArray(n.SessionStart)?n.SessionStart:[]).filter(c=>{try{return!JSON.stringify(c).includes("session:codex-context")}catch{return!0}}),i=e.binary??"toolnet-memory";return s.push({matcher:"startup|resume|clear|compact",hooks:[{type:"command",command:`${St(i)} session:codex-context`,timeout:15,additionalContextLimit:1e3,statusMessage:"Loading ToolNet project continuity"}]}),n.SessionStart=s,It(o,JSON.stringify(t,null,2)+`
758
+ `,{encoding:"utf8",mode:384}),o}import{spawnSync as Rt}from"node:child_process";function ae(e,o){return Rt(e,o,{encoding:"utf8",stdio:["ignore","pipe","pipe"]})}function ao(e,o){let t=ae(e,["mcp","get",o,"--json"]);if(t.status!==0||!t.stdout)return null;try{return JSON.parse(t.stdout)}catch{return null}}function lo(e,o){return e.enabled!==!1&&e.transport?.type==="stdio"&&e.transport?.command===o&&Array.isArray(e.transport?.args)&&e.transport?.args.length===1&&e.transport.args[0]==="mcp"}function go(e={}){let o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=e.codexBinary??"codex",n=e.serverName??"toolnet-memory",r=ao(t,n);if(r&&lo(r,o))return{installed:!0,changed:!1,serverName:n,command:o,args:["mcp"]};if(r){let c=ae(t,["mcp","remove",n]);if(c.status!==0)return{installed:!1,changed:!1,serverName:n,command:o,args:["mcp"],error:(c.stderr||c.stdout||"Unable to remove old ToolNet MCP configuration.").trim()}}let s=ae(t,["mcp","add",n,"--",o,"mcp"]);if(s.status!==0)return{installed:!1,changed:!1,serverName:n,command:o,args:["mcp"],error:(s.stderr||s.stdout||"Unable to register ToolNet MCP.").trim()};let i=ao(t,n);return!i||!lo(i,o)?{installed:!1,changed:!0,serverName:n,command:o,args:["mcp"],error:"Codex accepted MCP registration but verification did not match expected ToolNet command."}:{installed:!0,changed:!0,serverName:n,command:o,args:["mcp"]}}import{existsSync as ht,mkdirSync as Dt,readFileSync as bt,renameSync as Pt,rmSync as wt,writeFileSync as Ut}from"node:fs";import{dirname as Kt}from"node:path";function U(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function kt(e){return/^[A-Za-z0-9_./:-]+$/u.test(e)?e:`'${e.replace(/'/gu,"'\\''")}'`}function Bt(e){if(!ht(e))return{};let o;try{o=JSON.parse(bt(e,"utf8"))}catch(t){throw new Error(`Invalid existing Claude settings.json: ${t instanceof Error?t.message:String(t)}`)}if(!U(o))throw new Error("Invalid existing Claude settings.json: root must be a JSON object.");return o}function le(e){if(e===void 0)return[];if(!Array.isArray(e))throw new Error("Invalid existing Claude settings.json: hook event must be an array.");let o=[];for(let t of e){if(!U(t)){o.push(t);continue}let n=t.hooks;if(!Array.isArray(n)){o.push(t);continue}let r=n.filter(s=>{if(!U(s))return!0;let i=s.command;return!(typeof i=="string"&&i.includes("session:claude-hook"))});r.length!==0&&o.push({...t,hooks:r})}return o}function ge(e){return{type:"command",command:e,timeout:10}}function Ft(e,o){Dt(Kt(e),{recursive:!0,mode:448});let t=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{Ut(t,JSON.stringify(o,null,2)+`
759
+ `,{encoding:"utf8",mode:384}),Pt(t,e)}finally{wt(t,{force:!0})}}function Eo(e={}){let o=e.settingsFile??Pe(),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=Bt(o),r=n.hooks;if(r!==void 0&&!U(r))throw new Error("Invalid existing Claude settings.json: hooks must be an object.");let s=U(r)?{...r}:{},i=`${kt(t)} session:claude-hook`,c=le(s.SessionStart);c.push({matcher:"startup|resume|clear|compact",hooks:[ge(i)]}),s.SessionStart=c;let a=le(s.PostToolUse);a.push({matcher:"Edit|Write",hooks:[ge(i)]}),s.PostToolUse=a;let g=le(s.Stop);g.push({hooks:[ge(i)]}),s.Stop=g;let d={...n,hooks:s},f=JSON.stringify(n),_=JSON.stringify(d);return f===_?{settingsFile:o,changed:!1}:(Ft(o,d),{settingsFile:o,changed:!0})}import{existsSync as xt,mkdirSync as $t,readFileSync as Yt,renameSync as vt,rmSync as Gt,writeFileSync as jt}from"node:fs";import{dirname as Ht}from"node:path";function K(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function _o(e){if(!xt(e))return{};let o;try{o=JSON.parse(Yt(e,"utf8"))}catch(t){throw new Error(`Invalid existing Claude Code config: ${t instanceof Error?t.message:String(t)}`)}if(!K(o))throw new Error("Invalid existing Claude Code config: root must be a JSON object.");return o}function mo(e,o){if(!K(e))return!1;let t=e.args;return e.type==="stdio"&&e.command===o&&Array.isArray(t)&&t.length===1&&t[0]==="mcp"}function qt(e,o){$t(Ht(e),{recursive:!0});let t=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{jt(t,JSON.stringify(o,null,2)+`
760
+ `,{encoding:"utf8",mode:384}),vt(t,e)}finally{Gt(t,{force:!0})}}function uo(e={}){let o=e.stateFile??we(),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=e.serverName??"toolnet-memory",r=_o(o),s=r.mcpServers;if(s!==void 0&&!K(s))throw new Error("Invalid existing Claude Code config: mcpServers must be an object.");let i=K(s)?{...s}:{},c=i[n];if(mo(c,t))return{installed:!0,changed:!1,configFile:o,serverName:n,command:[t,"mcp"],repaired:!1};let a=c!==void 0;i[n]={type:"stdio",command:t,args:["mcp"]},qt(o,{...r,mcpServers:i});let d=_o(o).mcpServers;if(!K(d)||!mo(d[n],t))throw new Error("Claude Code MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:o,serverName:n,command:[t,"mcp"],repaired:a}}function fo(e={}){let o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=Eo({binary:o,settingsFile:e.settingsFile}),n=uo({binary:o,stateFile:e.stateFile});return{hooks:t,mcp:n,files:[t.settingsFile,n.configFile]}}function Oo(){return Ue()}function de(e={}){let o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=[],n=Oo(),r=new Map(n.map(s=>[s.agent,s.detected]));if(!(e.force===!0||r.get("agy")===!0))t.push({agent:"agy",detected:!1,installed:!1,targets:[]});else try{let i=je({binary:o});t.push({agent:"agy",detected:!0,installed:!0,targets:i.files})}catch(i){t.push({agent:"agy",detected:!0,installed:!1,targets:[],error:i instanceof Error?i.message:String(i)})}if(!(e.force===!0||r.get("opencode")===!0))t.push({agent:"opencode",detected:!1,installed:!1,targets:[]});else try{let i=We({binary:o}),c=eo({binary:o});t.push({agent:"opencode",detected:!0,installed:!0,targets:[i,c.configFile,`mcp:${c.serverName}`]})}catch(i){t.push({agent:"opencode",detected:!0,installed:!1,targets:[],error:i instanceof Error?i.message:String(i)})}if(!(e.force===!0||r.get("claude")===!0))t.push({agent:"claude",detected:!1,installed:!1,targets:[]});else try{let i=fo({binary:o});t.push({agent:"claude",detected:!0,installed:!0,targets:[i.hooks.settingsFile,i.mcp.configFile,`mcp:${i.mcp.serverName}`]})}catch(i){t.push({agent:"claude",detected:!0,installed:!1,targets:[],error:i instanceof Error?i.message:String(i)})}if(!(e.force===!0||r.get("codex")===!0))t.push({agent:"codex",detected:!1,installed:!1,targets:[]});else try{let i=io({binary:o}),c=co({binary:o}),a=go({binary:o});if(!a.installed)throw new Error(a.error??"Codex MCP registration failed");let g=[i.configFile,c,`mcp:${a.serverName}`];i.preservedPrevious&&g.push(i.previousFile),t.push({agent:"codex",detected:!0,installed:!0,targets:g})}catch(i){t.push({agent:"codex",detected:!0,installed:!1,targets:[],error:i instanceof Error?i.message:String(i)})}return t}function Vt(e){console.log(""),console.log("ToolNet Memory Integration Detection"),console.log("===================================="),console.log("");for(let o of e){let t=o.agent==="agy"?"Agy / Antigravity":o.agent==="opencode"?"OpenCode":o.agent==="claude"?"Claude Code":"Codex";if(!o.detected){console.log(`\u25CB ${t}: not detected`);continue}console.log(`\u2713 ${t}: detected`);for(let n of o.evidence)console.log(` ${n}`)}console.log("")}function Jt(e){console.log(""),console.log("ToolNet Memory AI Integrations"),console.log("=============================="),console.log("");for(let o of e){let t=o.agent==="agy"?"Agy / Antigravity":o.agent==="opencode"?"OpenCode":"Codex";if(!o.detected){console.log(`- ${t}: not detected`);continue}if(o.installed){console.log(`\u2713 ${t}: automatic memory enabled`);continue}console.log(`\u2717 ${t}: integration failed`),o.error&&console.log(` ${o.error}`)}console.log("")}async function Wt(){let e=process.argv.slice(2),o=e.includes("--all"),t=e.includes("--json");if(e.includes("--detect-only")){let s=Oo();if(t){console.log(JSON.stringify(s,null,2));return}Vt(s);return}let r=de({force:o});if(t){console.log(JSON.stringify(r,null,2));return}Jt(r)}var Xt=process.argv[1]&&(process.argv[1].endsWith("auto-integrate.js")||process.argv[1].endsWith("auto-integrate.ts"));Xt&&Wt().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});var Ee=B.join(_e.homedir(),".config","toolnet-memory"),p=B.join(Ee,".env"),en=new Set(["MEMORY_STORAGE_PROVIDER","R2_ACCOUNT_ID","R2_BUCKET","R2_ACCESS_KEY_ID","R2_SECRET_ACCESS_KEY","S3_ENDPOINT","S3_REGION","S3_BUCKET","S3_ACCESS_KEY_ID","S3_SECRET_ACCESS_KEY","S3_FORCE_PATH_STYLE","HF_NAMESPACE","HF_BUCKET","HF_S3_ACCESS_KEY_ID","HF_S3_SECRET_ACCESS_KEY","HF_URL","HF_TOKEN","HF_EMBEDDING_MODEL","TOOLNET_LLM_PROVIDER","TOOLNET_LLM_API_KEY","TOOLNET_LLM_BASE_URL","TOOLNET_LLM_MODEL","TOOLNET_LLM_FALLBACK_1_PROVIDER","TOOLNET_LLM_FALLBACK_1_API_KEY","TOOLNET_LLM_FALLBACK_1_BASE_URL","TOOLNET_LLM_FALLBACK_1_MODEL","TOOLNET_LLM_FALLBACK_1_ACCOUNT_ID","TOOLNET_LLM_FALLBACK_2_PROVIDER","TOOLNET_LLM_FALLBACK_2_API_KEY","TOOLNET_LLM_FALLBACK_2_BASE_URL","TOOLNET_LLM_FALLBACK_2_MODEL","TOOLNET_LLM_FALLBACK_2_ACCOUNT_ID","TOOLNET_LLM_FALLBACK_COOLDOWN_MS","TOOLNET_LLM_MAX_RETRIES","TOOLNET_LLM_ACCOUNT_ID","TOOLNET_EMBEDDING_PROVIDER","TOOLNET_EMBEDDING_API_KEY","TOOLNET_EMBEDDING_BASE_URL","TOOLNET_EMBEDDING_MODEL","TOOLNET_EMBEDDING_ACCOUNT_ID","MEMORY_LOCAL_STORAGE_PATH","MEMORY_LOCAL_CACHE_MB","MEMORY_AUTO_CAPTURE","MEMORY_AUTO_RETRIEVE","MEMORY_AUTO_SUMMARIZE","MEMORY_AUTO_SYNC","MEMORY_MAX_CANDIDATES","MEMORY_RERANK_TOP","MEMORY_FINAL_CONTEXT","MEMORY_TOKEN_BUDGET","TOOLNET_SESSION_LEARNING","TOOLNET_WORK_CONTINUITY","TOOLNET_SEMANTIC_CONTINUITY","TOOLNET_SMART_HANDOFF"]);function on(e){let o=new Map;for(let t of e.split(/\r?\n/)){let n=t.trim();if(!n||n.startsWith("#"))continue;let r=n.indexOf("=");if(r===-1)continue;let s=n.slice(0,r).trim(),i=n.slice(r+1).trim();s&&o.set(s,i)}return o}function N(e){let o=e.get("MEMORY_STORAGE_PROVIDER")?.trim();return o==="r2"||o==="s3"||o==="local"||o==="huggingface"?o:e.get("R2_ACCOUNT_ID")&&e.get("R2_BUCKET")?"r2":e.get("S3_BUCKET")?"s3":e.get("HF_BUCKET")&&e.get("HF_S3_ACCESS_KEY_ID")?"huggingface":e.get("MEMORY_LOCAL_STORAGE_PATH")?"local":"r2"}function F(e){switch(e){case"r2":return"Cloudflare R2";case"s3":return"S3 / S3-compatible";case"huggingface":return"Hugging Face S3";case"local":return"Local";default:return e}}function Ao(e){switch(e){case"r2":return["R2_ACCOUNT_ID","R2_BUCKET","R2_ACCESS_KEY_ID","R2_SECRET_ACCESS_KEY"];case"s3":return["S3_BUCKET","S3_ACCESS_KEY_ID","S3_SECRET_ACCESS_KEY"];case"huggingface":return["HF_BUCKET","HF_S3_ACCESS_KEY_ID","HF_S3_SECRET_ACCESS_KEY"];case"local":return[];default:return[]}}function yo(e){let o=N(e);return o==="local"?!0:Ao(o).every(t=>!!e.get(t)?.trim())}function me(e){return e?e.length<=8?"configured":`${e.slice(0,4)}\u2022\u2022\u2022\u2022${e.slice(-3)}`:"not configured"}function tn(e){let t=["# ==========================================================","# TOOLNET MEMORY","# Generated by: toolnet-memory setup","# Do not commit this file.","# ==========================================================","",`MEMORY_STORAGE_PROVIDER=${N(e)}`,"","# ----------------------------------------------------------","# Cloudflare R2","# ----------------------------------------------------------",`R2_ACCOUNT_ID=${e.get("R2_ACCOUNT_ID")??""}`,`R2_BUCKET=${e.get("R2_BUCKET")??"toolnet-memory"}`,`R2_ACCESS_KEY_ID=${e.get("R2_ACCESS_KEY_ID")??""}`,`R2_SECRET_ACCESS_KEY=${e.get("R2_SECRET_ACCESS_KEY")??""}`,"","# ----------------------------------------------------------","# Generic S3 / S3-compatible","# ----------------------------------------------------------",`S3_ENDPOINT=${e.get("S3_ENDPOINT")??""}`,`S3_REGION=${e.get("S3_REGION")??"us-east-1"}`,`S3_BUCKET=${e.get("S3_BUCKET")??"toolnet-memory"}`,`S3_ACCESS_KEY_ID=${e.get("S3_ACCESS_KEY_ID")??""}`,`S3_SECRET_ACCESS_KEY=${e.get("S3_SECRET_ACCESS_KEY")??""}`,`S3_FORCE_PATH_STYLE=${e.get("S3_FORCE_PATH_STYLE")??"false"}`,"","# ----------------------------------------------------------","# Hugging Face S3","# ----------------------------------------------------------",`HF_NAMESPACE=${e.get("HF_NAMESPACE")??""}`,`HF_BUCKET=${e.get("HF_BUCKET")??"toolnet-memory"}`,`HF_S3_ACCESS_KEY_ID=${e.get("HF_S3_ACCESS_KEY_ID")??""}`,`HF_S3_SECRET_ACCESS_KEY=${e.get("HF_S3_SECRET_ACCESS_KEY")??""}`,`HF_URL=${e.get("HF_URL")??""}`,"","# ----------------------------------------------------------","# AI / LLM - canonical ToolNet configuration","# ----------------------------------------------------------",`TOOLNET_LLM_PROVIDER=${e.get("TOOLNET_LLM_PROVIDER")??""}`,`TOOLNET_LLM_API_KEY=${e.get("TOOLNET_LLM_API_KEY")??""}`,`TOOLNET_LLM_BASE_URL=${e.get("TOOLNET_LLM_BASE_URL")??""}`,`TOOLNET_LLM_MODEL=${e.get("TOOLNET_LLM_MODEL")??""}`,`TOOLNET_LLM_ACCOUNT_ID=${e.get("TOOLNET_LLM_ACCOUNT_ID")??""}`,"","# ----------------------------------------------------------","# LLM fallback chain","# ----------------------------------------------------------",`TOOLNET_LLM_FALLBACK_1_PROVIDER=${e.get("TOOLNET_LLM_FALLBACK_1_PROVIDER")??""}`,`TOOLNET_LLM_FALLBACK_1_API_KEY=${e.get("TOOLNET_LLM_FALLBACK_1_API_KEY")??""}`,`TOOLNET_LLM_FALLBACK_1_BASE_URL=${e.get("TOOLNET_LLM_FALLBACK_1_BASE_URL")??""}`,`TOOLNET_LLM_FALLBACK_1_MODEL=${e.get("TOOLNET_LLM_FALLBACK_1_MODEL")??""}`,`TOOLNET_LLM_FALLBACK_1_ACCOUNT_ID=${e.get("TOOLNET_LLM_FALLBACK_1_ACCOUNT_ID")??""}`,`TOOLNET_LLM_FALLBACK_2_PROVIDER=${e.get("TOOLNET_LLM_FALLBACK_2_PROVIDER")??""}`,`TOOLNET_LLM_FALLBACK_2_API_KEY=${e.get("TOOLNET_LLM_FALLBACK_2_API_KEY")??""}`,`TOOLNET_LLM_FALLBACK_2_BASE_URL=${e.get("TOOLNET_LLM_FALLBACK_2_BASE_URL")??""}`,`TOOLNET_LLM_FALLBACK_2_MODEL=${e.get("TOOLNET_LLM_FALLBACK_2_MODEL")??""}`,`TOOLNET_LLM_FALLBACK_2_ACCOUNT_ID=${e.get("TOOLNET_LLM_FALLBACK_2_ACCOUNT_ID")??""}`,`TOOLNET_LLM_FALLBACK_COOLDOWN_MS=${e.get("TOOLNET_LLM_FALLBACK_COOLDOWN_MS")??"60000"}`,`TOOLNET_LLM_MAX_RETRIES=${e.get("TOOLNET_LLM_MAX_RETRIES")??"1"}`,"","# ----------------------------------------------------------","# Embedding - canonical ToolNet configuration","# ----------------------------------------------------------",`TOOLNET_EMBEDDING_PROVIDER=${e.get("TOOLNET_EMBEDDING_PROVIDER")??""}`,`TOOLNET_EMBEDDING_API_KEY=${e.get("TOOLNET_EMBEDDING_API_KEY")??""}`,`TOOLNET_EMBEDDING_BASE_URL=${e.get("TOOLNET_EMBEDDING_BASE_URL")??""}`,`TOOLNET_EMBEDDING_MODEL=${e.get("TOOLNET_EMBEDDING_MODEL")??""}`,`TOOLNET_EMBEDDING_ACCOUNT_ID=${e.get("TOOLNET_EMBEDDING_ACCOUNT_ID")??""}`,"","# ----------------------------------------------------------","# Embedding - legacy/current compatibility","# ----------------------------------------------------------",`HF_TOKEN=${e.get("HF_TOKEN")??""}`,`HF_EMBEDDING_MODEL=${e.get("HF_EMBEDDING_MODEL")??"sentence-transformers/all-MiniLM-L6-v2"}`,"","# ----------------------------------------------------------","# Local storage/cache","# ----------------------------------------------------------",`MEMORY_LOCAL_STORAGE_PATH=${e.get("MEMORY_LOCAL_STORAGE_PATH")??""}`,`MEMORY_LOCAL_CACHE_MB=${e.get("MEMORY_LOCAL_CACHE_MB")??"200"}`,"","# ----------------------------------------------------------","# Automation","# ----------------------------------------------------------",`MEMORY_AUTO_CAPTURE=${e.get("MEMORY_AUTO_CAPTURE")??"true"}`,`MEMORY_AUTO_RETRIEVE=${e.get("MEMORY_AUTO_RETRIEVE")??"true"}`,`MEMORY_AUTO_SUMMARIZE=${e.get("MEMORY_AUTO_SUMMARIZE")??"true"}`,`MEMORY_AUTO_SYNC=${e.get("MEMORY_AUTO_SYNC")??"true"}`,"","# ----------------------------------------------------------","# Retrieval","# ----------------------------------------------------------",`MEMORY_MAX_CANDIDATES=${e.get("MEMORY_MAX_CANDIDATES")??"50"}`,`MEMORY_RERANK_TOP=${e.get("MEMORY_RERANK_TOP")??"10"}`,`MEMORY_FINAL_CONTEXT=${e.get("MEMORY_FINAL_CONTEXT")??"5"}`,`MEMORY_TOKEN_BUDGET=${e.get("MEMORY_TOKEN_BUDGET")??"2000"}`,"","# ----------------------------------------------------------","# Automatic Session Memory","# ----------------------------------------------------------",`TOOLNET_SESSION_LEARNING=${e.get("TOOLNET_SESSION_LEARNING")??"1"}`,`TOOLNET_WORK_CONTINUITY=${e.get("TOOLNET_WORK_CONTINUITY")??"1"}`,`TOOLNET_SEMANTIC_CONTINUITY=${e.get("TOOLNET_SEMANTIC_CONTINUITY")??"1"}`,`TOOLNET_SMART_HANDOFF=${e.get("TOOLNET_SMART_HANDOFF")??"1"}`],n=[...e.entries()].filter(([r])=>!en.has(r));if(n.length>0){t.push("","# ----------------------------------------------------------","# Preserved settings","# ----------------------------------------------------------");for(let[r,s]of n)t.push(`${r}=${s}`)}return`${t.join(`
714
761
  `)}
715
- `}function m(e){A.mkdirSync(te,{recursive:!0,mode:448});let o=`${L}.tmp-${process.pid}`;A.writeFileSync(o,zo(e),{encoding:"utf8",mode:384}),A.renameSync(o,L),A.chmodSync(te,448),A.chmodSync(L,384)}function p(e,o,t,n){let r=t.trim();if(r){e.set(o,r);return}!e.get(o)&&n!==void 0&&e.set(o,n)}async function R(e,o){return T.isTTY?(e.pause(),b.write(o),new Promise(t=>{let n="",r=!1,i=()=>{r||(r=!0,T.off("data",s),T.setRawMode?.(!1),T.pause(),b.write(`
716
- `),e.resume(),t(n))},s=a=>{for(let l of a.toString("utf8")){if(l==="\r"||l===`
717
- `){i();return}if(l===""&&(T.off("data",s),T.setRawMode?.(!1),b.write(`
718
- `),process.exit(130)),l==="\x7F"){n=n.slice(0,-1);continue}n+=l}};T.resume(),T.setRawMode?.(!0),T.on("data",s)})):""}function C(e){return e.trim().replace(/\/+$/,"")}function qe(e){return`https://${e}.r2.cloudflarestorage.com`}async function ie(e){let o=new AbortController,t=setTimeout(()=>o.abort(),15e3);t.unref?.();let n=new Jo({region:e.region,endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}});try{return await n.send(new Vo({Bucket:e.bucket}),{abortSignal:o.signal}),{ok:!0,message:`Bucket "${e.bucket}" reachable`}}catch(r){return{ok:!1,message:r instanceof Error?r.message:String(r)}}finally{clearTimeout(t),n.destroy()}}async function Qo(e){let o=e.get("R2_ACCOUNT_ID")?.trim()??"",t=e.get("R2_BUCKET")?.trim()??"",n=e.get("R2_ACCESS_KEY_ID")?.trim()??"",r=e.get("R2_SECRET_ACCESS_KEY")?.trim()??"";return!o||!t||!n||!r?{ok:!1,message:"R2 configuration is incomplete"}:ie({endpoint:qe(o),region:"auto",bucket:t,accessKeyId:n,secretAccessKey:r})}async function Zo(e){let o=C(e.get("S3_ENDPOINT")??""),t=e.get("S3_REGION")?.trim()||"us-east-1",n=e.get("S3_BUCKET")?.trim()??"",r=e.get("S3_ACCESS_KEY_ID")?.trim()??"",i=e.get("S3_SECRET_ACCESS_KEY")?.trim()??"";return!n||!r||!i?{ok:!1,message:"S3 configuration is incomplete"}:ie({endpoint:o||void 0,region:t,bucket:n,accessKeyId:r,secretAccessKey:i,forcePathStyle:e.get("S3_FORCE_PATH_STYLE")==="true"})}async function et(e){let o=C(e.get("HF_URL")??""),t=e.get("HF_BUCKET")?.trim()??"",n=e.get("HF_S3_ACCESS_KEY_ID")?.trim()??"",r=e.get("HF_S3_SECRET_ACCESS_KEY")?.trim()??"";return o?!t||!n||!r?{ok:!1,message:"Hugging Face S3 configuration is incomplete"}:ie({endpoint:o,region:"us-east-1",bucket:t,accessKeyId:n,secretAccessKey:r,forcePathStyle:!0}):{ok:!1,message:"HF_URL / S3 endpoint is required for connection test"}}async function ot(e){let o=e.get("MEMORY_LOCAL_STORAGE_PATH")?.trim()||P.join(ne.homedir(),".local","share","toolnet-memory"),t=P.join(o,`.toolnet-test-${process.pid}-${Date.now()}`);try{return A.mkdirSync(o,{recursive:!0,mode:448}),A.writeFileSync(t,`toolnet-memory
719
- `,{encoding:"utf8",mode:384}),A.unlinkSync(t),{ok:!0,message:`Writable: ${o}`}}catch(n){return{ok:!1,message:n instanceof Error?n.message:String(n)}}}async function tt(e,o){switch(e){case"r2":return Qo(o);case"s3":return Zo(o);case"huggingface":return et(o);case"local":return ot(o)}}async function nt(e,o){console.log(""),console.log(`Testing ${U(e)}...`);let t=await tt(e,o);return t.ok?console.log(`\u2713 ${t.message}`):(console.log("\u2717 Connection test failed"),console.log(` ${t.message}`)),console.log(""),t}function rt(){console.log(""),console.log("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"),console.log("\u2551 TOOLNET MEMORY SETUP \u2551"),console.log("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"),console.log("")}function it(e){let o=I(e);console.log("Current configuration"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),console.log(`Storage : ${U(o)} ${Ge(e)?"\u2713":"\u26A0 incomplete"}`);let t=e.get("TOOLNET_LLM_PROVIDER"),n=e.get("TOOLNET_LLM_MODEL"),r=e.get("TOOLNET_EMBEDDING_PROVIDER");console.log(`LLM : ${t?`${M(t)}${n?` / ${n}`:""}`:"not configured"}`),console.log(`Embedding: ${r||"legacy/default"}`),console.log("")}async function st(e){console.log("Setup"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),console.log(" 1. Storage"),console.log(" 2. AI Model"),console.log(" 3. Finish & Save"),console.log(" 0. Exit without saving"),console.log("");let o=(await e.question("Choose [1-3]: ")).trim();return o==="1"?"storage":o==="2"?"ai":o==="0"?"exit":"finish"}async function ct(e,o){console.log(""),console.log("Storage"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),console.log(` 1. Cloudflare R2${o==="r2"?" \u2713 current":""}`),console.log(` 2. S3 / S3-compatible${o==="s3"?" \u2713 current":""}`),console.log(` 3. Hugging Face S3${o==="huggingface"?" \u2713 current":""}`),console.log(` 4. Local${o==="local"?" \u2713 current":""}`),console.log(""),console.log(" 0. Back"),console.log("");let t=(await e.question("Choose storage: ")).trim();return t==="0"?"back":t==="2"?"s3":t==="3"?"huggingface":t==="4"?"local":"r2"}async function at(e,o){console.log(""),console.log("Cloudflare R2"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let t=await e.question(o.get("R2_ACCOUNT_ID")?`ACCOUNT ID [${o.get("R2_ACCOUNT_ID")}]: `:"ACCOUNT ID: "),n=await e.question(o.get("R2_ACCESS_KEY_ID")?`ACCESS KEY ID [${re(o.get("R2_ACCESS_KEY_ID"))}]: `:"ACCESS KEY ID: "),r=await e.question(`BUCKET [${o.get("R2_BUCKET")||"toolnet-memory"}]: `);p(o,"R2_ACCOUNT_ID",t),p(o,"R2_ACCESS_KEY_ID",n),p(o,"R2_BUCKET",r,"toolnet-memory");let i=o.get("R2_ACCOUNT_ID")?.trim();i&&console.log(`URL: ${qe(i)}`);let s=await R(e,o.get("R2_SECRET_ACCESS_KEY")?"SECRET ACCESS KEY [configured, Enter = keep]: ":"SECRET ACCESS KEY: ");s.trim()&&o.set("R2_SECRET_ACCESS_KEY",s.trim())}async function lt(e,o){console.log(""),console.log("S3 / S3-compatible"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let t=await e.question(o.get("S3_ENDPOINT")?`URL / ENDPOINT [${o.get("S3_ENDPOINT")}]: `:"URL / ENDPOINT [blank = AWS S3]: "),n=await e.question(`REGION [${o.get("S3_REGION")||"us-east-1"}]: `),r=await e.question(o.get("S3_ACCESS_KEY_ID")?`ACCESS KEY ID [${re(o.get("S3_ACCESS_KEY_ID"))}]: `:"ACCESS KEY ID: "),i=await e.question(`BUCKET [${o.get("S3_BUCKET")||"toolnet-memory"}]: `),s=o.get("S3_FORCE_PATH_STYLE")==="true",a=await e.question(`FORCE PATH STYLE [${s?"Y":"N"}] (y/n): `);if(t.trim()&&o.set("S3_ENDPOINT",C(t)),p(o,"S3_REGION",n,"us-east-1"),p(o,"S3_ACCESS_KEY_ID",r),p(o,"S3_BUCKET",i,"toolnet-memory"),a.trim()){let g=a.trim().toLowerCase();o.set("S3_FORCE_PATH_STYLE",g==="y"||g==="yes"?"true":"false")}else o.has("S3_FORCE_PATH_STYLE")||o.set("S3_FORCE_PATH_STYLE","false");let l=await R(e,o.get("S3_SECRET_ACCESS_KEY")?"SECRET ACCESS KEY [configured, Enter = keep]: ":"SECRET ACCESS KEY: ");l.trim()&&o.set("S3_SECRET_ACCESS_KEY",l.trim())}async function gt(e,o){console.log(""),console.log("Hugging Face S3"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let t=await e.question(o.get("HF_NAMESPACE")?`NAMESPACE [${o.get("HF_NAMESPACE")}]: `:"NAMESPACE [optional]: "),n=await e.question(o.get("HF_S3_ACCESS_KEY_ID")?`ACCESS KEY ID [${re(o.get("HF_S3_ACCESS_KEY_ID"))}]: `:"ACCESS KEY ID: "),r=await e.question(`BUCKET [${o.get("HF_BUCKET")||"toolnet-memory"}]: `),i=await e.question(o.get("HF_URL")?`URL [${o.get("HF_URL")}]: `:"URL / S3 ENDPOINT: ");p(o,"HF_NAMESPACE",t),p(o,"HF_S3_ACCESS_KEY_ID",n),p(o,"HF_BUCKET",r,"toolnet-memory"),i.trim()&&o.set("HF_URL",C(i));let s=await R(e,o.get("HF_S3_SECRET_ACCESS_KEY")?"SECRET ACCESS KEY [configured, Enter = keep]: ":"SECRET ACCESS KEY: ");s.trim()&&o.set("HF_S3_SECRET_ACCESS_KEY",s.trim())}async function dt(e,o){console.log(""),console.log("Local Storage"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let t=o.get("MEMORY_LOCAL_STORAGE_PATH")??P.join(ne.homedir(),".local","share","toolnet-memory"),n=await e.question(`LOCAL PATH [${t}]: `);p(o,"MEMORY_LOCAL_STORAGE_PATH",n,t)}async function Et(e,o){let t=new Map(o);for(;;){let n=await ct(e,I(o));if(n==="back")return;let r=new Map(o);o.set("MEMORY_STORAGE_PROVIDER",n),n==="r2"?await at(e,o):n==="s3"?await lt(e,o):n==="huggingface"?await gt(e,o):await dt(e,o);let i=xe(n).filter(l=>!o.get(l)?.trim());if(i.length){console.log(""),console.log("\u26A0 Missing required fields:");for(let g of i)console.log(` - ${g}`);console.log(""),console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let l=(await e.question("Choose [1]: ")).trim()||"1";if(l==="2"){m(o),console.log(""),console.log("\u26A0 Saved with incomplete configuration"),console.log("");return}if(l==="3"){o.clear();for(let[g,E]of r)o.set(g,E);continue}if(l==="4"){o.clear();for(let[g,E]of t)o.set(g,E);console.log(""),console.log("Storage changes cancelled."),console.log("");return}continue}if((await nt(n,o)).ok){m(o),console.log(`\u2713 ${U(n)} configuration saved`),console.log(` ${L}`),console.log("");return}console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let a=(await e.question("Choose [1]: ")).trim()||"1";if(a==="2"){m(o),console.log(""),console.log("\u26A0 Saved even though connection test failed"),console.log("");return}if(a==="3"){o.clear();for(let[l,g]of r)o.set(l,g);continue}if(a==="4"){o.clear();for(let[l,g]of t)o.set(l,g);console.log(""),console.log("Storage changes cancelled."),console.log("");return}}}var N=[{id:"openai-compatible",label:"OpenAI-compatible",apiKeyRequired:!0,baseUrlRequired:!0},{id:"alibaba",label:"Alibaba / DashScope",baseUrl:"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",suggestedModel:"qwen3.6-flash",apiKeyRequired:!0},{id:"openrouter",label:"OpenRouter",baseUrl:"https://openrouter.ai/api/v1",apiKeyRequired:!0},{id:"groq",label:"Groq",baseUrl:"https://api.groq.com/openai/v1",apiKeyRequired:!0},{id:"deepseek",label:"DeepSeek",baseUrl:"https://api.deepseek.com",suggestedModel:"deepseek-v4-flash",apiKeyRequired:!0},{id:"nvidia",label:"NVIDIA NIM",baseUrl:"https://integrate.api.nvidia.com/v1",suggestedModel:"deepseek-ai/deepseek-v4-pro",apiKeyRequired:!0},{id:"gemini",label:"Gemini",baseUrl:"https://generativelanguage.googleapis.com/v1beta",suggestedModel:"gemini-3.6-flash",apiKeyRequired:!0},{id:"huggingface",label:"Hugging Face",baseUrl:"https://router.huggingface.co/v1",apiKeyRequired:!0},{id:"ollama",label:"Ollama / Local",baseUrl:"http://127.0.0.1:11434/v1",apiKeyRequired:!1},{id:"custom",label:"Custom endpoint",apiKeyRequired:!1,baseUrlRequired:!0},{id:"cloudflare",label:"Cloudflare Workers AI",suggestedModel:"@cf/meta/llama-3.1-8b-instruct",apiKeyRequired:!0,accountIdRequired:!0}];function _t(e){return N.find(o=>o.id===e)}function M(e){return _t(e)?.label??e??"not configured"}function He(e){let o=e.get("TOOLNET_LLM_PROVIDER")?.trim();return N.some(t=>t.id===o)?o:void 0}async function se(e,o){console.log(""),console.log("AI Model"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),N.forEach((r,i)=>{console.log(` ${i+1}. ${r.label}${o===r.id?" \u2713 current":""}`)}),console.log(""),console.log(" 0. Back"),console.log("");let t=(await e.question("Choose provider: ")).trim();if(t==="0")return"back";let n=Number(t)-1;return Number.isInteger(n)&&n>=0&&n<N.length?N[n].id:(console.log(""),console.log("\u26A0 Invalid provider selection"),se(e,o))}function Ot(e,o){return!(!e.get("TOOLNET_LLM_MODEL")?.trim()||o.apiKeyRequired&&!e.get("TOOLNET_LLM_API_KEY")?.trim()||o.accountIdRequired&&!e.get("TOOLNET_LLM_ACCOUNT_ID")?.trim()||o.baseUrlRequired&&!e.get("TOOLNET_LLM_BASE_URL")?.trim())}function ft(e){e.delete("TOOLNET_LLM_API_KEY"),e.delete("TOOLNET_LLM_BASE_URL"),e.delete("TOOLNET_LLM_MODEL"),e.delete("TOOLNET_LLM_ACCOUNT_ID")}async function mt(e,o,t){console.log(""),console.log(t.label),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let n=o.get("TOOLNET_LLM_PROVIDER");if(n&&n!==t.id&&ft(o),o.set("TOOLNET_LLM_PROVIDER",t.id),t.accountIdRequired){let l=o.get("TOOLNET_LLM_ACCOUNT_ID"),g=await e.question(l?`ACCOUNT ID [${l}]: `:"ACCOUNT ID: ");p(o,"TOOLNET_LLM_ACCOUNT_ID",g)}else o.delete("TOOLNET_LLM_ACCOUNT_ID");if(t.apiKeyRequired||t.id==="custom"){let l=o.get("TOOLNET_LLM_API_KEY"),g=await R(e,l?"API KEY [configured, Enter = keep]: ":t.apiKeyRequired?"API KEY: ":"API KEY [optional]: ");g.trim()&&o.set("TOOLNET_LLM_API_KEY",g.trim())}else o.delete("TOOLNET_LLM_API_KEY");if(t.id!=="cloudflare"){let g=o.get("TOOLNET_LLM_BASE_URL")||t.baseUrl||"",u=(await e.question(g?`BASE URL [${g}]: `:t.baseUrlRequired?"BASE URL: ":"BASE URL [optional]: ")).trim()||g;u?o.set("TOOLNET_LLM_BASE_URL",C(u)):o.delete("TOOLNET_LLM_BASE_URL")}else o.delete("TOOLNET_LLM_BASE_URL");let i=o.get("TOOLNET_LLM_MODEL")||t.suggestedModel||"",a=(await e.question(i?`MODEL [${i}]: `:"MODEL: ")).trim()||i;a&&o.set("TOOLNET_LLM_MODEL",a)}function ut(e){let o=He(e);if(!o)throw new Error("AI provider is not configured");return{id:o,apiKey:e.get("TOOLNET_LLM_API_KEY")?.trim()||void 0,baseUrl:e.get("TOOLNET_LLM_BASE_URL")?.trim()||void 0,model:e.get("TOOLNET_LLM_MODEL")?.trim()||void 0,accountId:e.get("TOOLNET_LLM_ACCOUNT_ID")?.trim()||void 0}}async function Lt(e){let o=ut(e);console.log(""),console.log(`Testing ${M(o.id)}...`);try{let n=await _e(o).healthCheck();return n.ok?(console.log(`\u2713 Provider reachable${n.latencyMs?` (${n.latencyMs} ms)`:""}`),console.log(`\u2713 Model: ${n.model??o.model??"configured"}`),console.log(""),{ok:!0,message:n.message}):(console.log("\u2717 AI provider test failed"),console.log(` ${n.message}`),console.log(""),{ok:!1,message:n.message})}catch(t){let n=t instanceof Error?t.message:String(t);return console.log("\u2717 AI provider test failed"),console.log(` ${n}`),console.log(""),{ok:!1,message:n}}}var q=[{id:"local",label:"Local / Hash",apiKeyRequired:!1},{id:"huggingface",label:"Hugging Face",suggestedModel:"sentence-transformers/all-MiniLM-L6-v2",apiKeyRequired:!0},{id:"openai-compatible",label:"OpenAI-compatible",apiKeyRequired:!0,baseUrlRequired:!0},{id:"alibaba",label:"Alibaba / DashScope",baseUrl:"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",suggestedModel:"text-embedding-v4",apiKeyRequired:!0},{id:"openrouter",label:"OpenRouter",baseUrl:"https://openrouter.ai/api/v1",apiKeyRequired:!0},{id:"nvidia",label:"NVIDIA NIM",baseUrl:"https://integrate.api.nvidia.com/v1",apiKeyRequired:!0},{id:"ollama",label:"Ollama / Local",baseUrl:"http://127.0.0.1:11434/v1",apiKeyRequired:!1},{id:"gemini",label:"Gemini",baseUrl:"https://generativelanguage.googleapis.com/v1beta",suggestedModel:"gemini-embedding-001",apiKeyRequired:!0},{id:"cloudflare",label:"Cloudflare Workers AI",suggestedModel:"@cf/baai/bge-base-en-v1.5",apiKeyRequired:!0,accountIdRequired:!0},{id:"custom",label:"Custom OpenAI-compatible endpoint",apiKeyRequired:!1,baseUrlRequired:!0}];function ce(e){return q.find(o=>o.id===e)?.label??e??"not configured"}async function je(e,o){console.log(""),console.log("Embedding Model"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),q.forEach((r,i)=>{console.log(` ${i+1}. ${r.label}${o===r.id?" \u2713 current":""}`)}),console.log(""),console.log(" 0. Back"),console.log("");let t=(await e.question("Choose embedding provider: ")).trim();if(t==="0")return"back";let n=Number(t)-1;return Number.isInteger(n)&&n>=0&&n<q.length?q[n]:(console.log(""),console.log("\u26A0 Invalid selection"),je(e,o))}function Ye(e){e.delete("TOOLNET_EMBEDDING_API_KEY"),e.delete("TOOLNET_EMBEDDING_BASE_URL"),e.delete("TOOLNET_EMBEDDING_MODEL"),e.delete("TOOLNET_EMBEDDING_ACCOUNT_ID")}async function pt(e,o,t){let n=o.get("TOOLNET_EMBEDDING_PROVIDER");if(n&&n!==t.id&&Ye(o),o.set("TOOLNET_EMBEDDING_PROVIDER",t.id),console.log(""),console.log(t.label),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),t.id==="local"){Ye(o),console.log("\u2713 Local embedding selected"),console.log(" No API key required.");return}if(t.accountIdRequired){let l=o.get("TOOLNET_EMBEDDING_ACCOUNT_ID"),g=await e.question(l?`ACCOUNT ID [${l}]: `:"ACCOUNT ID: ");p(o,"TOOLNET_EMBEDDING_ACCOUNT_ID",g)}else o.delete("TOOLNET_EMBEDDING_ACCOUNT_ID");if(t.apiKeyRequired||t.id==="custom"){let l=o.get("TOOLNET_EMBEDDING_API_KEY"),g=await R(e,l?"API KEY [configured, Enter = keep]: ":t.apiKeyRequired?"API KEY: ":"API KEY [optional]: ");g.trim()&&o.set("TOOLNET_EMBEDDING_API_KEY",g.trim())}else o.delete("TOOLNET_EMBEDDING_API_KEY");if(t.id==="cloudflare"){let l=o.get("TOOLNET_EMBEDDING_ACCOUNT_ID")?.trim();if(l){let g=`https://api.cloudflare.com/client/v4/accounts/${l}/ai/v1`;o.set("TOOLNET_EMBEDDING_BASE_URL",g),console.log(`BASE URL: ${g}`)}}else{let g=o.get("TOOLNET_EMBEDDING_BASE_URL")||t.baseUrl||"",u=(await e.question(g?`BASE URL [${g}]: `:t.baseUrlRequired?"BASE URL: ":"BASE URL [optional]: ")).trim()||g;u&&o.set("TOOLNET_EMBEDDING_BASE_URL",C(u))}let i=o.get("TOOLNET_EMBEDDING_MODEL")||t.suggestedModel||"",a=(await e.question(i?`MODEL [${i}]: `:"MODEL: ")).trim()||i;a&&o.set("TOOLNET_EMBEDDING_MODEL",a)}function Tt(e,o){return o.id==="local"?!0:o.apiKeyRequired&&!e.get("TOOLNET_EMBEDDING_API_KEY")?.trim()||o.accountIdRequired&&!e.get("TOOLNET_EMBEDDING_ACCOUNT_ID")?.trim()||o.baseUrlRequired&&!e.get("TOOLNET_EMBEDDING_BASE_URL")?.trim()?!1:!!e.get("TOOLNET_EMBEDDING_MODEL")?.trim()}async function ve(e){let o=e.get("TOOLNET_EMBEDDING_PROVIDER")?.trim();if(console.log(""),console.log(`Testing embedding: ${ce(o)}...`),o==="local")return console.log("\u2713 Local embedding ready"),console.log(""),!0;let t=e.get("TOOLNET_EMBEDDING_API_KEY")?.trim(),n=e.get("TOOLNET_EMBEDDING_MODEL")?.trim(),r=e.get("TOOLNET_EMBEDDING_BASE_URL")?.trim();try{if(!n)throw new Error("Embedding model is missing");if(o==="huggingface"){if(!t)throw new Error("API key is missing");let i=await fetch(`https://router.huggingface.co/hf-inference/models/${n}/pipeline/feature-extraction`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({inputs:["toolnet memory test"]})});if(!i.ok)throw new Error(`HTTP ${i.status}: ${await i.text()}`)}else if(o==="gemini"){if(!t)throw new Error("API key is missing");let i=n.replace(/^models\//,"");r=r||"https://generativelanguage.googleapis.com/v1beta";let s=await fetch(`${r.replace(/\/+$/,"")}/models/${encodeURIComponent(i)}:embedContent?key=${encodeURIComponent(t)}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:`models/${i}`,content:{parts:[{text:"toolnet memory test"}]}})});if(!s.ok)throw new Error(`HTTP ${s.status}: ${await s.text()}`)}else{if(!r)throw new Error("BASE URL is missing");let i=await fetch(`${r.replace(/\/+$/,"")}/embeddings`,{method:"POST",headers:{"content-type":"application/json",...t?{authorization:`Bearer ${t}`}:{}},body:JSON.stringify({model:n,input:["toolnet memory test"]})});if(!i.ok)throw new Error(`HTTP ${i.status}: ${await i.text()}`);let s=await i.json();if(!Array.isArray(s.data)||!Array.isArray(s.data[0]?.embedding))throw new Error("Invalid embedding response")}return console.log("\u2713 Embedding provider reachable"),console.log(`\u2713 Model: ${n}`),console.log(""),!0}catch(i){return console.log("\u2717 Embedding test failed"),console.log(` ${i instanceof Error?i.message:String(i)}`),console.log(""),!1}}async function At(e,o){let t=new Map(o);for(;;){let n=await je(e,o.get("TOOLNET_EMBEDDING_PROVIDER"));if(n==="back")return;if(await pt(e,o,n),!Tt(o,n)){console.log(""),console.log("\u26A0 Embedding configuration is incomplete."),console.log(""),console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let s=(await e.question("Choose [1]: ")).trim()||"1";if(s==="2"){m(o);return}if(s==="3")continue;if(s==="4"){o.clear();for(let[a,l]of t)o.set(a,l);return}continue}if(await ve(o)){m(o),console.log(`\u2713 ${n.label} embedding configuration saved`),console.log(` ${L}`),console.log("");return}console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let i=(await e.question("Choose [1]: ")).trim()||"1";if(i==="2"){m(o);return}if(i!=="3"&&i==="4"){o.clear();for(let[s,a]of t)o.set(s,a);return}}}async function Mt(e,o){let t=o.get("TOOLNET_LLM_PROVIDER")?.trim();if(!t){console.log(""),console.log("\u26A0 Configure LLM first."),console.log("");return}if(t==="deepseek"||t==="groq"){console.log(""),console.log(`\u26A0 ${M(t)} is configured as LLM-only.`),console.log("Choose Embedding separately."),console.log("");return}o.set("TOOLNET_EMBEDDING_PROVIDER",t);let n=o.get("TOOLNET_LLM_API_KEY"),r=o.get("TOOLNET_LLM_BASE_URL"),i=o.get("TOOLNET_LLM_ACCOUNT_ID");n&&o.set("TOOLNET_EMBEDDING_API_KEY",n),r&&o.set("TOOLNET_EMBEDDING_BASE_URL",r),i&&o.set("TOOLNET_EMBEDDING_ACCOUNT_ID",i);let s="";t==="alibaba"?s="text-embedding-v4":t==="gemini"?s="gemini-embedding-001":t==="cloudflare"?s="@cf/baai/bge-base-en-v1.5":t==="huggingface"&&(s="sentence-transformers/all-MiniLM-L6-v2");let l=(await e.question(s?`EMBEDDING MODEL [${s}]: `:"EMBEDDING MODEL: ")).trim()||s;if(!l){console.log(""),console.log("\u26A0 Embedding model is required."),console.log("");return}if(o.set("TOOLNET_EMBEDDING_MODEL",l),!await ve(o)){let E=(await e.question("Save anyway? (y/N): ")).trim().toLowerCase();if(E!=="y"&&E!=="yes")return}m(o),console.log(""),console.log("\u2713 LLM credentials reused for Embedding"),console.log(`\u2713 Embedding model: ${l}`),console.log("")}function H(e){return`TOOLNET_LLM_FALLBACK_${e}`}function j(e,o){let t=H(o);for(let n of["PROVIDER","API_KEY","BASE_URL","MODEL","ACCOUNT_ID"])e.delete(`${t}_${n}`)}function $e(e,o){let t=H(o),n=e.get(`${t}_PROVIDER`);if(!n)return"not configured";let r=e.get(`${t}_MODEL`);return`${M(n)}${r?` / ${r}`:""}`}async function Fe(e,o,t){console.log(""),console.log(`Fallback ${t}`),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let n=await se(e,void 0);if(n==="back")return;let r=o.get("TOOLNET_LLM_PROVIDER");if(n===r){console.log(""),console.log("\u26A0 Fallback cannot be the same provider as Primary."),console.log("");return}let i=t===1?2:1,s=o.get(`${H(i)}_PROVIDER`);if(n===s){console.log(""),console.log("\u26A0 This provider is already used by the other fallback."),console.log("");return}let a=N.find(O=>O.id===n);if(!a)return;let l=H(t);if(j(o,t),o.set(`${l}_PROVIDER`,n),a.accountIdRequired){let O=await e.question("ACCOUNT ID: ");O.trim()&&o.set(`${l}_ACCOUNT_ID`,O.trim())}if(a.apiKeyRequired||n==="custom"){let O=await R(e,a.apiKeyRequired?"API KEY: ":"API KEY [optional]: ");O.trim()&&o.set(`${l}_API_KEY`,O.trim())}if(n==="cloudflare"){let O=o.get(`${l}_ACCOUNT_ID`);O&&o.set(`${l}_BASE_URL`,`https://api.cloudflare.com/client/v4/accounts/${O}/ai`)}else{let O=a.baseUrl??"",ae=(await e.question(O?`BASE URL [${O}]: `:a.baseUrlRequired?"BASE URL: ":"BASE URL [optional]: ")).trim()||O;ae&&o.set(`${l}_BASE_URL`,C(ae))}let g=a.suggestedModel??"",u=(await e.question(g?`MODEL [${g}]: `:"MODEL: ")).trim()||g;if(!u){console.log(""),console.log("\u26A0 MODEL is required."),console.log(""),j(o,t);return}o.set(`${l}_MODEL`,u),m(o),console.log(""),console.log(`\u2713 Fallback ${t} saved`),console.log(` ${M(n)} / ${u}`),console.log("")}async function Nt(e,o){let t=o.get("TOOLNET_LLM_FALLBACK_COOLDOWN_MS")||"60000",n=o.get("TOOLNET_LLM_MAX_RETRIES")||"1";console.log(""),console.log("Fallback Policy"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let r=await e.question(`COOLDOWN MS [${t}]: `);if(r.trim()){let s=Number(r.trim());Number.isFinite(s)&&s>=0?o.set("TOOLNET_LLM_FALLBACK_COOLDOWN_MS",String(Math.floor(s))):console.log("\u26A0 Invalid cooldown; keeping previous value.")}let i=await e.question(`MAX RETRIES [${n}]: `);if(i.trim()){let s=Number(i.trim());Number.isFinite(s)&&s>=0&&s<=5?o.set("TOOLNET_LLM_MAX_RETRIES",String(Math.floor(s))):console.log("\u26A0 MAX RETRIES must be between 0 and 5.")}m(o),console.log(""),console.log("\u2713 Fallback policy saved"),console.log("")}async function It(e,o){for(;;){console.log(""),console.log("LLM Fallback"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),console.log(` Primary : ${o.get("TOOLNET_LLM_PROVIDER")?`${M(o.get("TOOLNET_LLM_PROVIDER"))} / ${o.get("TOOLNET_LLM_MODEL")||"model not configured"}`:"not configured"}`),console.log(` Fallback 1 : ${$e(o,1)}`),console.log(` Fallback 2 : ${$e(o,2)}`),console.log(` Cooldown : ${o.get("TOOLNET_LLM_FALLBACK_COOLDOWN_MS")||"60000"} ms`),console.log(` Retries : ${o.get("TOOLNET_LLM_MAX_RETRIES")||"1"}`),console.log(""),console.log(" 1. Configure Fallback 1"),console.log(" 2. Configure Fallback 2"),console.log(" 3. Remove Fallback 1"),console.log(" 4. Remove Fallback 2"),console.log(" 5. Retry / cooldown settings"),console.log(" 0. Back"),console.log("");let t=(await e.question("Choose: ")).trim();if(t==="0")return;if(t==="1"){await Fe(e,o,1);continue}if(t==="2"){await Fe(e,o,2);continue}if(t==="3"){j(o,1),m(o),console.log(""),console.log("\u2713 Fallback 1 removed"),console.log("");continue}if(t==="4"){j(o,2),m(o),console.log(""),console.log("\u2713 Fallback 2 removed"),console.log("");continue}if(t==="5"){await Nt(e,o);continue}console.log(""),console.log("\u26A0 Invalid selection")}}async function Ct(e,o){for(;;){console.log(""),console.log("AI Model"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let t=o.get("TOOLNET_LLM_PROVIDER"),n=o.get("TOOLNET_EMBEDDING_PROVIDER");console.log(` LLM : ${t?`${M(t)} / ${o.get("TOOLNET_LLM_MODEL")||"model not configured"}`:"not configured"}`),console.log(` Embedding : ${n?`${ce(n)} / ${o.get("TOOLNET_EMBEDDING_MODEL")||(n==="local"?"local hash":"model not configured")}`:"legacy/default"}`),console.log(""),console.log(" 1. Configure LLM"),console.log(" 2. Configure Embedding"),console.log(" 3. Use LLM provider credentials for Embedding"),console.log(" 4. Configure LLM Fallbacks"),console.log(" 0. Back"),console.log("");let r=(await e.question("Choose: ")).trim();if(r==="0")return;if(r==="1"){await St(e,o);continue}if(r==="2"){await At(e,o);continue}if(r==="3"){await Mt(e,o);continue}if(r==="4"){await It(e,o);continue}console.log(""),console.log("\u26A0 Invalid selection")}}async function St(e,o){let t=new Map(o);for(;;){let n=await se(e,He(o));if(n==="back")return;let r=N.find(a=>a.id===n);if(!r)continue;if(await mt(e,o,r),!Ot(o,r)){console.log(""),console.log("\u26A0 AI configuration is incomplete."),console.log(""),console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let a=(await e.question("Choose [1]: ")).trim()||"1";if(a==="2"){m(o),console.log(""),console.log("\u26A0 AI configuration saved without validation"),console.log(` ${L}`),console.log("");return}if(a==="3")continue;if(a==="4"){o.clear();for(let[l,g]of t)o.set(l,g);console.log(""),console.log("AI changes cancelled."),console.log("");return}continue}if((await Lt(o)).ok){m(o),console.log(`\u2713 ${r.label} configuration saved`),console.log(` ${L}`),console.log("");return}console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let s=(await e.question("Choose [1]: ")).trim()||"1";if(s==="2"){m(o),console.log(""),console.log("\u26A0 AI configuration saved even though provider test failed"),console.log(` ${L}`),console.log("");return}if(s!=="3"&&s==="4"){o.clear();for(let[a,l]of t)o.set(a,l);console.log(""),console.log("AI changes cancelled."),console.log("");return}}}function yt(){try{let o=oe().filter(t=>t.installed);if(o.length===0)return;console.log(""),console.log("Automatic AI memory");for(let t of o){let n=t.agent==="agy"?"Agy / Antigravity":t.agent==="opencode"?"OpenCode":t.agent==="codex"?"Codex":t.agent;console.log(` \u2713 ${n}`)}}catch{}}function d(e,...o){for(let t of o){let n=e.get(t)?.trim();if(n)return n}}function _(e,o,t){t&&!e.get(o)?.trim()&&e.set(o,t)}function Rt(e){let o=!1,t=JSON.stringify([...e.entries()]);if(!e.get("TOOLNET_LLM_PROVIDER")?.trim()){let i;d(e,"GROQ_API_KEY")?i="groq":d(e,"DEEPSEEK_API_KEY")?i="deepseek":d(e,"NVIDIA_API_KEY","NVIDIA_NIM_API_KEY")?i="nvidia":d(e,"OPENROUTER_API_KEY")?i="openrouter":d(e,"ALIBABA_API_KEY","DASHSCOPE_API_KEY")?i="alibaba":d(e,"GEMINI_API_KEY","GOOGLE_API_KEY")?i="gemini":d(e,"CLOUDFLARE_API_TOKEN")&&d(e,"CLOUDFLARE_ACCOUNT_ID")?i="cloudflare":d(e,"HF_TOKEN")?i="huggingface":d(e,"OLLAMA_MODEL","OLLAMA_BASE_URL")?i="ollama":d(e,"OPENAI_API_KEY","MODEL_API_KEY")&&(i="openai-compatible"),i&&e.set("TOOLNET_LLM_PROVIDER",i)}switch(e.get("TOOLNET_LLM_PROVIDER")?.trim()){case"groq":_(e,"TOOLNET_LLM_API_KEY",d(e,"GROQ_API_KEY")),_(e,"TOOLNET_LLM_BASE_URL",d(e,"GROQ_BASE_URL")||"https://api.groq.com/openai/v1"),_(e,"TOOLNET_LLM_MODEL",d(e,"GROQ_MODEL"));break;case"deepseek":_(e,"TOOLNET_LLM_API_KEY",d(e,"DEEPSEEK_API_KEY")),_(e,"TOOLNET_LLM_BASE_URL",d(e,"DEEPSEEK_BASE_URL")||"https://api.deepseek.com"),_(e,"TOOLNET_LLM_MODEL",d(e,"DEEPSEEK_MODEL")||"deepseek-v4-flash");break;case"nvidia":_(e,"TOOLNET_LLM_API_KEY",d(e,"NVIDIA_API_KEY","NVIDIA_NIM_API_KEY")),_(e,"TOOLNET_LLM_BASE_URL",d(e,"NVIDIA_BASE_URL","NVIDIA_NIM_BASE_URL")||"https://integrate.api.nvidia.com/v1"),_(e,"TOOLNET_LLM_MODEL",d(e,"NVIDIA_MODEL","NVIDIA_NIM_MODEL"));break;case"openrouter":_(e,"TOOLNET_LLM_API_KEY",d(e,"OPENROUTER_API_KEY")),_(e,"TOOLNET_LLM_BASE_URL",d(e,"OPENROUTER_BASE_URL")||"https://openrouter.ai/api/v1"),_(e,"TOOLNET_LLM_MODEL",d(e,"OPENROUTER_MODEL"));break;case"alibaba":_(e,"TOOLNET_LLM_API_KEY",d(e,"ALIBABA_API_KEY","DASHSCOPE_API_KEY")),_(e,"TOOLNET_LLM_BASE_URL",d(e,"ALIBABA_BASE_URL","DASHSCOPE_BASE_URL")),_(e,"TOOLNET_LLM_MODEL",d(e,"ALIBABA_MODEL","DASHSCOPE_MODEL"));break;case"gemini":_(e,"TOOLNET_LLM_API_KEY",d(e,"GEMINI_API_KEY","GOOGLE_API_KEY")),_(e,"TOOLNET_LLM_BASE_URL",d(e,"GEMINI_BASE_URL")||"https://generativelanguage.googleapis.com/v1beta"),_(e,"TOOLNET_LLM_MODEL",d(e,"GEMINI_MODEL"));break;case"huggingface":_(e,"TOOLNET_LLM_API_KEY",d(e,"HF_TOKEN")),_(e,"TOOLNET_LLM_BASE_URL",d(e,"HF_INFERENCE_BASE_URL")||"https://router.huggingface.co/v1"),_(e,"TOOLNET_LLM_MODEL",d(e,"HF_LLM_MODEL","HF_MODEL"));break;case"ollama":_(e,"TOOLNET_LLM_API_KEY",d(e,"OLLAMA_API_KEY")),_(e,"TOOLNET_LLM_BASE_URL",d(e,"OLLAMA_BASE_URL")||"http://127.0.0.1:11434/v1"),_(e,"TOOLNET_LLM_MODEL",d(e,"OLLAMA_MODEL"));break;case"cloudflare":_(e,"TOOLNET_LLM_API_KEY",d(e,"CLOUDFLARE_API_TOKEN")),_(e,"TOOLNET_LLM_ACCOUNT_ID",d(e,"CLOUDFLARE_ACCOUNT_ID")),_(e,"TOOLNET_LLM_MODEL",d(e,"CLOUDFLARE_MODEL"));break;case"openai-compatible":_(e,"TOOLNET_LLM_API_KEY",d(e,"OPENAI_API_KEY","MODEL_API_KEY")),_(e,"TOOLNET_LLM_BASE_URL",d(e,"OPENAI_BASE_URL","MODEL_BASE_URL")),_(e,"TOOLNET_LLM_MODEL",d(e,"OPENAI_MODEL","MODEL_NAME"));break}!e.get("TOOLNET_EMBEDDING_PROVIDER")?.trim()&&d(e,"HF_TOKEN")&&(e.set("TOOLNET_EMBEDDING_PROVIDER","huggingface"),_(e,"TOOLNET_EMBEDDING_API_KEY",d(e,"HF_TOKEN")),_(e,"TOOLNET_EMBEDDING_MODEL",d(e,"HF_EMBEDDING_MODEL")||"sentence-transformers/all-MiniLM-L6-v2"));let r=JSON.stringify([...e.entries()]);return o=t!==r,o}function G(e,o="not configured"){return e?.trim()||o}function Dt(e){let o=U(I(e)),t=e.get("TOOLNET_LLM_PROVIDER"),n=e.get("TOOLNET_LLM_MODEL"),r=e.get("TOOLNET_EMBEDDING_PROVIDER"),i=e.get("TOOLNET_EMBEDDING_MODEL"),s=e.get("TOOLNET_LLM_FALLBACK_1_PROVIDER"),a=e.get("TOOLNET_LLM_FALLBACK_2_PROVIDER");console.log(""),console.log("TOOLNET MEMORY READY"),console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"),console.log(`Storage : ${o}`),console.log(`LLM : ${t?`${M(t)} / ${G(n)}`:"not configured"}`),console.log(`Fallback 1 : ${s?`${M(s)} / ${G(e.get("TOOLNET_LLM_FALLBACK_1_MODEL"))}`:"none"}`),console.log(`Fallback 2 : ${a?`${M(a)} / ${G(e.get("TOOLNET_LLM_FALLBACK_2_MODEL"))}`:"none"}`),console.log(`Embedding : ${r?`${r==="local"?"Local / Hash":ce(r)} / ${G(i,r==="local"?"local hash":"not configured")}`:"legacy/default"}`),console.log(""),console.log(`Config : ${L}`),console.log(`Permissions: ${A.statSync(L).mode.toString(8).slice(-3)}`),console.log(""),console.log("Secrets : hidden"),console.log("Config mode: canonical TOOLNET_*"),console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")}function Ve(e){Rt(e),e.has("TOOLNET_LLM_FALLBACK_COOLDOWN_MS")||e.set("TOOLNET_LLM_FALLBACK_COOLDOWN_MS","60000"),e.has("TOOLNET_LLM_MAX_RETRIES")||e.set("TOOLNET_LLM_MAX_RETRIES","1"),e.has("MEMORY_STORAGE_PROVIDER")||e.set("MEMORY_STORAGE_PROVIDER",I(e)),e.has("MEMORY_LOCAL_CACHE_MB")||e.set("MEMORY_LOCAL_CACHE_MB","200"),e.has("MEMORY_AUTO_CAPTURE")||e.set("MEMORY_AUTO_CAPTURE","true"),e.has("MEMORY_AUTO_RETRIEVE")||e.set("MEMORY_AUTO_RETRIEVE","true"),e.has("MEMORY_AUTO_SUMMARIZE")||e.set("MEMORY_AUTO_SUMMARIZE","true"),e.has("MEMORY_AUTO_SYNC")||e.set("MEMORY_AUTO_SYNC","true"),e.has("MEMORY_MAX_CANDIDATES")||e.set("MEMORY_MAX_CANDIDATES","50"),e.has("MEMORY_RERANK_TOP")||e.set("MEMORY_RERANK_TOP","10"),e.has("MEMORY_FINAL_CONTEXT")||e.set("MEMORY_FINAL_CONTEXT","5"),e.has("MEMORY_TOKEN_BUDGET")||e.set("MEMORY_TOKEN_BUDGET","2000"),e.has("TOOLNET_SESSION_LEARNING")||e.set("TOOLNET_SESSION_LEARNING","1"),e.has("TOOLNET_WORK_CONTINUITY")||e.set("TOOLNET_WORK_CONTINUITY","1"),e.has("TOOLNET_SEMANTIC_CONTINUITY")||e.set("TOOLNET_SEMANTIC_CONTINUITY","1"),e.has("TOOLNET_SMART_HANDOFF")||e.set("TOOLNET_SMART_HANDOFF","1")}async function ht(e,o){Ve(e),o||m(e),console.log("TOOLNET MEMORY SETUP"),console.log(""),console.log("Interactive terminal not detected."),console.log(`Config: ${L}`),console.log(`Storage: ${U(I(e))}`),console.log(""),console.log("Run from an interactive terminal to configure providers:"),console.log(" toolnet-memory setup")}async function bt(){let e=A.existsSync(L),o=e?Xo(A.readFileSync(L,"utf8")):new Map,t=new Map(o);if(Ve(t),!T.isTTY||!b.isTTY){await ht(t,e);return}let n=vo.createInterface({input:T,output:b}),r=!1;try{for(;;){rt(),it(t);let i=await st(n);if(i==="storage"){let s=JSON.stringify([...t.entries()]);await Et(n,t),r=r||s!==JSON.stringify([...t.entries()]);continue}if(i==="ai"){let s=JSON.stringify([...t.entries()]);await Ct(n,t),r=r||s!==JSON.stringify([...t.entries()]);continue}if(i==="exit"){if(!r){console.log(""),console.log("No changes made.");return}console.log("");let s=(await n.question("Discard unsaved changes? (y/N): ")).trim().toLowerCase();if(s==="y"||s==="yes"){console.log(""),console.log("Changes discarded.");return}continue}m(t),Ge(t)||(console.log(""),console.log("\u26A0 Storage configuration is incomplete.")),yt(),Dt(t),console.log(""),console.log("Validate:"),console.log(" toolnet-memory provider:status"),console.log(" toolnet-memory provider:test"),console.log(" toolnet-memory doctor"),console.log("");return}}finally{n.close()}}bt().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});
762
+ `}function O(e){A.mkdirSync(Ee,{recursive:!0,mode:448});let o=`${p}.tmp-${process.pid}`;A.writeFileSync(o,tn(e),{encoding:"utf8",mode:384}),A.renameSync(o,p),A.chmodSync(Ee,448),A.chmodSync(p,384)}function L(e,o,t,n){let r=t.trim();if(r){e.set(o,r);return}!e.get(o)&&n!==void 0&&e.set(o,n)}async function b(e,o){return T.isTTY?(e.pause(),k.write(o),new Promise(t=>{let n="",r=!1,s=()=>{r||(r=!0,T.off("data",i),T.setRawMode?.(!1),T.pause(),k.write(`
763
+ `),e.resume(),t(n))},i=c=>{for(let a of c.toString("utf8")){if(a==="\r"||a===`
764
+ `){s();return}if(a===""&&(T.off("data",i),T.setRawMode?.(!1),k.write(`
765
+ `),process.exit(130)),a==="\x7F"){n=n.slice(0,-1);continue}n+=a}};T.resume(),T.setRawMode?.(!0),T.on("data",i)})):""}function C(e){return e.trim().replace(/\/+$/,"")}function Mo(e){return`https://${e}.r2.cloudflarestorage.com`}async function ue(e){let o=new AbortController,t=setTimeout(()=>o.abort(),15e3);t.unref?.();let n=new Zt({region:e.region,endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}});try{return await n.send(new Qt({Bucket:e.bucket}),{abortSignal:o.signal}),{ok:!0,message:`Bucket "${e.bucket}" reachable`}}catch(r){return{ok:!1,message:r instanceof Error?r.message:String(r)}}finally{clearTimeout(t),n.destroy()}}async function nn(e){let o=e.get("R2_ACCOUNT_ID")?.trim()??"",t=e.get("R2_BUCKET")?.trim()??"",n=e.get("R2_ACCESS_KEY_ID")?.trim()??"",r=e.get("R2_SECRET_ACCESS_KEY")?.trim()??"";return!o||!t||!n||!r?{ok:!1,message:"R2 configuration is incomplete"}:ue({endpoint:Mo(o),region:"auto",bucket:t,accessKeyId:n,secretAccessKey:r})}async function rn(e){let o=C(e.get("S3_ENDPOINT")??""),t=e.get("S3_REGION")?.trim()||"us-east-1",n=e.get("S3_BUCKET")?.trim()??"",r=e.get("S3_ACCESS_KEY_ID")?.trim()??"",s=e.get("S3_SECRET_ACCESS_KEY")?.trim()??"";return!n||!r||!s?{ok:!1,message:"S3 configuration is incomplete"}:ue({endpoint:o||void 0,region:t,bucket:n,accessKeyId:r,secretAccessKey:s,forcePathStyle:e.get("S3_FORCE_PATH_STYLE")==="true"})}async function sn(e){let o=C(e.get("HF_URL")??""),t=e.get("HF_BUCKET")?.trim()??"",n=e.get("HF_S3_ACCESS_KEY_ID")?.trim()??"",r=e.get("HF_S3_SECRET_ACCESS_KEY")?.trim()??"";return o?!t||!n||!r?{ok:!1,message:"Hugging Face S3 configuration is incomplete"}:ue({endpoint:o,region:"us-east-1",bucket:t,accessKeyId:n,secretAccessKey:r,forcePathStyle:!0}):{ok:!1,message:"HF_URL / S3 endpoint is required for connection test"}}async function cn(e){let o=e.get("MEMORY_LOCAL_STORAGE_PATH")?.trim()||B.join(_e.homedir(),".local","share","toolnet-memory"),t=B.join(o,`.toolnet-test-${process.pid}-${Date.now()}`);try{return A.mkdirSync(o,{recursive:!0,mode:448}),A.writeFileSync(t,`toolnet-memory
766
+ `,{encoding:"utf8",mode:384}),A.unlinkSync(t),{ok:!0,message:`Writable: ${o}`}}catch(n){return{ok:!1,message:n instanceof Error?n.message:String(n)}}}async function an(e,o){switch(e){case"r2":return nn(o);case"s3":return rn(o);case"huggingface":return sn(o);case"local":return cn(o)}}async function ln(e,o){console.log(""),console.log(`Testing ${F(e)}...`);let t=await an(e,o);return t.ok?console.log(`\u2713 ${t.message}`):(console.log("\u2717 Connection test failed"),console.log(` ${t.message}`)),console.log(""),t}function gn(){console.log(""),console.log("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"),console.log("\u2551 TOOLNET MEMORY SETUP \u2551"),console.log("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"),console.log("")}function dn(e){let o=N(e);console.log("Current configuration"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),console.log(`Storage : ${F(o)} ${yo(e)?"\u2713":"\u26A0 incomplete"}`);let t=e.get("TOOLNET_LLM_PROVIDER"),n=e.get("TOOLNET_LLM_MODEL"),r=e.get("TOOLNET_EMBEDDING_PROVIDER");console.log(`LLM : ${t?`${y(t)}${n?` / ${n}`:""}`:"not configured"}`),console.log(`Embedding: ${r||"legacy/default"}`),console.log("")}async function En(e){console.log("Setup"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),console.log(" 1. Storage"),console.log(" 2. AI Model"),console.log(" 3. Finish & Save"),console.log(" 0. Exit without saving"),console.log("");let o=(await e.question("Choose [1-3]: ")).trim();return o==="1"?"storage":o==="2"?"ai":o==="0"?"exit":"finish"}async function _n(e,o){console.log(""),console.log("Storage"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),console.log(` 1. Cloudflare R2${o==="r2"?" \u2713 current":""}`),console.log(` 2. S3 / S3-compatible${o==="s3"?" \u2713 current":""}`),console.log(` 3. Hugging Face S3${o==="huggingface"?" \u2713 current":""}`),console.log(` 4. Local${o==="local"?" \u2713 current":""}`),console.log(""),console.log(" 0. Back"),console.log("");let t=(await e.question("Choose storage: ")).trim();return t==="0"?"back":t==="2"?"s3":t==="3"?"huggingface":t==="4"?"local":"r2"}async function mn(e,o){console.log(""),console.log("Cloudflare R2"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let t=await e.question(o.get("R2_ACCOUNT_ID")?`ACCOUNT ID [${o.get("R2_ACCOUNT_ID")}]: `:"ACCOUNT ID: "),n=await e.question(o.get("R2_ACCESS_KEY_ID")?`ACCESS KEY ID [${me(o.get("R2_ACCESS_KEY_ID"))}]: `:"ACCESS KEY ID: "),r=await e.question(`BUCKET [${o.get("R2_BUCKET")||"toolnet-memory"}]: `);L(o,"R2_ACCOUNT_ID",t),L(o,"R2_ACCESS_KEY_ID",n),L(o,"R2_BUCKET",r,"toolnet-memory");let s=o.get("R2_ACCOUNT_ID")?.trim();s&&console.log(`URL: ${Mo(s)}`);let i=await b(e,o.get("R2_SECRET_ACCESS_KEY")?"SECRET ACCESS KEY [configured, Enter = keep]: ":"SECRET ACCESS KEY: ");i.trim()&&o.set("R2_SECRET_ACCESS_KEY",i.trim())}async function un(e,o){console.log(""),console.log("S3 / S3-compatible"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let t=await e.question(o.get("S3_ENDPOINT")?`URL / ENDPOINT [${o.get("S3_ENDPOINT")}]: `:"URL / ENDPOINT [blank = AWS S3]: "),n=await e.question(`REGION [${o.get("S3_REGION")||"us-east-1"}]: `),r=await e.question(o.get("S3_ACCESS_KEY_ID")?`ACCESS KEY ID [${me(o.get("S3_ACCESS_KEY_ID"))}]: `:"ACCESS KEY ID: "),s=await e.question(`BUCKET [${o.get("S3_BUCKET")||"toolnet-memory"}]: `),i=o.get("S3_FORCE_PATH_STYLE")==="true",c=await e.question(`FORCE PATH STYLE [${i?"Y":"N"}] (y/n): `);if(t.trim()&&o.set("S3_ENDPOINT",C(t)),L(o,"S3_REGION",n,"us-east-1"),L(o,"S3_ACCESS_KEY_ID",r),L(o,"S3_BUCKET",s,"toolnet-memory"),c.trim()){let g=c.trim().toLowerCase();o.set("S3_FORCE_PATH_STYLE",g==="y"||g==="yes"?"true":"false")}else o.has("S3_FORCE_PATH_STYLE")||o.set("S3_FORCE_PATH_STYLE","false");let a=await b(e,o.get("S3_SECRET_ACCESS_KEY")?"SECRET ACCESS KEY [configured, Enter = keep]: ":"SECRET ACCESS KEY: ");a.trim()&&o.set("S3_SECRET_ACCESS_KEY",a.trim())}async function fn(e,o){console.log(""),console.log("Hugging Face S3"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let t=await e.question(o.get("HF_NAMESPACE")?`NAMESPACE [${o.get("HF_NAMESPACE")}]: `:"NAMESPACE [optional]: "),n=await e.question(o.get("HF_S3_ACCESS_KEY_ID")?`ACCESS KEY ID [${me(o.get("HF_S3_ACCESS_KEY_ID"))}]: `:"ACCESS KEY ID: "),r=await e.question(`BUCKET [${o.get("HF_BUCKET")||"toolnet-memory"}]: `),s=await e.question(o.get("HF_URL")?`URL [${o.get("HF_URL")}]: `:"URL / S3 ENDPOINT: ");L(o,"HF_NAMESPACE",t),L(o,"HF_S3_ACCESS_KEY_ID",n),L(o,"HF_BUCKET",r,"toolnet-memory"),s.trim()&&o.set("HF_URL",C(s));let i=await b(e,o.get("HF_S3_SECRET_ACCESS_KEY")?"SECRET ACCESS KEY [configured, Enter = keep]: ":"SECRET ACCESS KEY: ");i.trim()&&o.set("HF_S3_SECRET_ACCESS_KEY",i.trim())}async function On(e,o){console.log(""),console.log("Local Storage"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let t=o.get("MEMORY_LOCAL_STORAGE_PATH")??B.join(_e.homedir(),".local","share","toolnet-memory"),n=await e.question(`LOCAL PATH [${t}]: `);L(o,"MEMORY_LOCAL_STORAGE_PATH",n,t)}async function pn(e,o){let t=new Map(o);for(;;){let n=await _n(e,N(o));if(n==="back")return;let r=new Map(o);o.set("MEMORY_STORAGE_PROVIDER",n),n==="r2"?await mn(e,o):n==="s3"?await un(e,o):n==="huggingface"?await fn(e,o):await On(e,o);let s=Ao(n).filter(a=>!o.get(a)?.trim());if(s.length){console.log(""),console.log("\u26A0 Missing required fields:");for(let g of s)console.log(` - ${g}`);console.log(""),console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let a=(await e.question("Choose [1]: ")).trim()||"1";if(a==="2"){O(o),console.log(""),console.log("\u26A0 Saved with incomplete configuration"),console.log("");return}if(a==="3"){o.clear();for(let[g,d]of r)o.set(g,d);continue}if(a==="4"){o.clear();for(let[g,d]of t)o.set(g,d);console.log(""),console.log("Storage changes cancelled."),console.log("");return}continue}if((await ln(n,o)).ok){O(o),console.log(`\u2713 ${F(n)} configuration saved`),console.log(` ${p}`),console.log("");return}console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let c=(await e.question("Choose [1]: ")).trim()||"1";if(c==="2"){O(o),console.log(""),console.log("\u26A0 Saved even though connection test failed"),console.log("");return}if(c==="3"){o.clear();for(let[a,g]of r)o.set(a,g);continue}if(c==="4"){o.clear();for(let[a,g]of t)o.set(a,g);console.log(""),console.log("Storage changes cancelled."),console.log("");return}}}var I=[{id:"openai-compatible",label:"OpenAI-compatible",apiKeyRequired:!0,baseUrlRequired:!0},{id:"alibaba",label:"Alibaba / DashScope",baseUrl:"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",suggestedModel:"qwen3.6-flash",apiKeyRequired:!0},{id:"openrouter",label:"OpenRouter",baseUrl:"https://openrouter.ai/api/v1",apiKeyRequired:!0},{id:"groq",label:"Groq",baseUrl:"https://api.groq.com/openai/v1",apiKeyRequired:!0},{id:"deepseek",label:"DeepSeek",baseUrl:"https://api.deepseek.com",suggestedModel:"deepseek-v4-flash",apiKeyRequired:!0},{id:"nvidia",label:"NVIDIA NIM",baseUrl:"https://integrate.api.nvidia.com/v1",suggestedModel:"deepseek-ai/deepseek-v4-pro",apiKeyRequired:!0},{id:"gemini",label:"Gemini",baseUrl:"https://generativelanguage.googleapis.com/v1beta",suggestedModel:"gemini-3.6-flash",apiKeyRequired:!0},{id:"huggingface",label:"Hugging Face",baseUrl:"https://router.huggingface.co/v1",apiKeyRequired:!0},{id:"ollama",label:"Ollama / Local",baseUrl:"http://127.0.0.1:11434/v1",apiKeyRequired:!1},{id:"custom",label:"Custom endpoint",apiKeyRequired:!1,baseUrlRequired:!0},{id:"cloudflare",label:"Cloudflare Workers AI",suggestedModel:"@cf/meta/llama-3.1-8b-instruct",apiKeyRequired:!0,accountIdRequired:!0}];function Ln(e){return I.find(o=>o.id===e)}function y(e){return Ln(e)?.label??e??"not configured"}function Io(e){let o=e.get("TOOLNET_LLM_PROVIDER")?.trim();return I.some(t=>t.id===o)?o:void 0}async function fe(e,o){console.log(""),console.log("AI Model"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),I.forEach((r,s)=>{console.log(` ${s+1}. ${r.label}${o===r.id?" \u2713 current":""}`)}),console.log(""),console.log(" 0. Back"),console.log("");let t=(await e.question("Choose provider: ")).trim();if(t==="0")return"back";let n=Number(t)-1;return Number.isInteger(n)&&n>=0&&n<I.length?I[n].id:(console.log(""),console.log("\u26A0 Invalid provider selection"),fe(e,o))}function Tn(e,o){return!(!e.get("TOOLNET_LLM_MODEL")?.trim()||o.apiKeyRequired&&!e.get("TOOLNET_LLM_API_KEY")?.trim()||o.accountIdRequired&&!e.get("TOOLNET_LLM_ACCOUNT_ID")?.trim()||o.baseUrlRequired&&!e.get("TOOLNET_LLM_BASE_URL")?.trim())}function An(e){e.delete("TOOLNET_LLM_API_KEY"),e.delete("TOOLNET_LLM_BASE_URL"),e.delete("TOOLNET_LLM_MODEL"),e.delete("TOOLNET_LLM_ACCOUNT_ID")}async function yn(e,o,t){console.log(""),console.log(t.label),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let n=o.get("TOOLNET_LLM_PROVIDER");if(n&&n!==t.id&&An(o),o.set("TOOLNET_LLM_PROVIDER",t.id),t.accountIdRequired){let a=o.get("TOOLNET_LLM_ACCOUNT_ID"),g=await e.question(a?`ACCOUNT ID [${a}]: `:"ACCOUNT ID: ");L(o,"TOOLNET_LLM_ACCOUNT_ID",g)}else o.delete("TOOLNET_LLM_ACCOUNT_ID");if(t.apiKeyRequired||t.id==="custom"){let a=o.get("TOOLNET_LLM_API_KEY"),g=await b(e,a?"API KEY [configured, Enter = keep]: ":t.apiKeyRequired?"API KEY: ":"API KEY [optional]: ");g.trim()&&o.set("TOOLNET_LLM_API_KEY",g.trim())}else o.delete("TOOLNET_LLM_API_KEY");if(t.id!=="cloudflare"){let g=o.get("TOOLNET_LLM_BASE_URL")||t.baseUrl||"",f=(await e.question(g?`BASE URL [${g}]: `:t.baseUrlRequired?"BASE URL: ":"BASE URL [optional]: ")).trim()||g;f?o.set("TOOLNET_LLM_BASE_URL",C(f)):o.delete("TOOLNET_LLM_BASE_URL")}else o.delete("TOOLNET_LLM_BASE_URL");let s=o.get("TOOLNET_LLM_MODEL")||t.suggestedModel||"",c=(await e.question(s?`MODEL [${s}]: `:"MODEL: ")).trim()||s;c&&o.set("TOOLNET_LLM_MODEL",c)}function Mn(e){let o=Io(e);if(!o)throw new Error("AI provider is not configured");return{id:o,apiKey:e.get("TOOLNET_LLM_API_KEY")?.trim()||void 0,baseUrl:e.get("TOOLNET_LLM_BASE_URL")?.trim()||void 0,model:e.get("TOOLNET_LLM_MODEL")?.trim()||void 0,accountId:e.get("TOOLNET_LLM_ACCOUNT_ID")?.trim()||void 0}}async function In(e){let o=Mn(e);console.log(""),console.log(`Testing ${y(o.id)}...`);try{let n=await Me(o).healthCheck();return n.ok?(console.log(`\u2713 Provider reachable${n.latencyMs?` (${n.latencyMs} ms)`:""}`),console.log(`\u2713 Model: ${n.model??o.model??"configured"}`),console.log(""),{ok:!0,message:n.message}):(console.log("\u2717 AI provider test failed"),console.log(` ${n.message}`),console.log(""),{ok:!1,message:n.message})}catch(t){let n=t instanceof Error?t.message:String(t);return console.log("\u2717 AI provider test failed"),console.log(` ${n}`),console.log(""),{ok:!1,message:n}}}var z=[{id:"local",label:"Local / Hash",apiKeyRequired:!1},{id:"huggingface",label:"Hugging Face",suggestedModel:"sentence-transformers/all-MiniLM-L6-v2",apiKeyRequired:!0},{id:"openai-compatible",label:"OpenAI-compatible",apiKeyRequired:!0,baseUrlRequired:!0},{id:"alibaba",label:"Alibaba / DashScope",baseUrl:"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",suggestedModel:"text-embedding-v4",apiKeyRequired:!0},{id:"openrouter",label:"OpenRouter",baseUrl:"https://openrouter.ai/api/v1",apiKeyRequired:!0},{id:"nvidia",label:"NVIDIA NIM",baseUrl:"https://integrate.api.nvidia.com/v1",apiKeyRequired:!0},{id:"ollama",label:"Ollama / Local",baseUrl:"http://127.0.0.1:11434/v1",apiKeyRequired:!1},{id:"gemini",label:"Gemini",baseUrl:"https://generativelanguage.googleapis.com/v1beta",suggestedModel:"gemini-embedding-001",apiKeyRequired:!0},{id:"cloudflare",label:"Cloudflare Workers AI",suggestedModel:"@cf/baai/bge-base-en-v1.5",apiKeyRequired:!0,accountIdRequired:!0},{id:"custom",label:"Custom OpenAI-compatible endpoint",apiKeyRequired:!1,baseUrlRequired:!0}];function Oe(e){return z.find(o=>o.id===e)?.label??e??"not configured"}async function No(e,o){console.log(""),console.log("Embedding Model"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),z.forEach((r,s)=>{console.log(` ${s+1}. ${r.label}${o===r.id?" \u2713 current":""}`)}),console.log(""),console.log(" 0. Back"),console.log("");let t=(await e.question("Choose embedding provider: ")).trim();if(t==="0")return"back";let n=Number(t)-1;return Number.isInteger(n)&&n>=0&&n<z.length?z[n]:(console.log(""),console.log("\u26A0 Invalid selection"),No(e,o))}function po(e){e.delete("TOOLNET_EMBEDDING_API_KEY"),e.delete("TOOLNET_EMBEDDING_BASE_URL"),e.delete("TOOLNET_EMBEDDING_MODEL"),e.delete("TOOLNET_EMBEDDING_ACCOUNT_ID")}async function Nn(e,o,t){let n=o.get("TOOLNET_EMBEDDING_PROVIDER");if(n&&n!==t.id&&po(o),o.set("TOOLNET_EMBEDDING_PROVIDER",t.id),console.log(""),console.log(t.label),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),t.id==="local"){po(o),console.log("\u2713 Local embedding selected"),console.log(" No API key required.");return}if(t.accountIdRequired){let a=o.get("TOOLNET_EMBEDDING_ACCOUNT_ID"),g=await e.question(a?`ACCOUNT ID [${a}]: `:"ACCOUNT ID: ");L(o,"TOOLNET_EMBEDDING_ACCOUNT_ID",g)}else o.delete("TOOLNET_EMBEDDING_ACCOUNT_ID");if(t.apiKeyRequired||t.id==="custom"){let a=o.get("TOOLNET_EMBEDDING_API_KEY"),g=await b(e,a?"API KEY [configured, Enter = keep]: ":t.apiKeyRequired?"API KEY: ":"API KEY [optional]: ");g.trim()&&o.set("TOOLNET_EMBEDDING_API_KEY",g.trim())}else o.delete("TOOLNET_EMBEDDING_API_KEY");if(t.id==="cloudflare"){let a=o.get("TOOLNET_EMBEDDING_ACCOUNT_ID")?.trim();if(a){let g=`https://api.cloudflare.com/client/v4/accounts/${a}/ai/v1`;o.set("TOOLNET_EMBEDDING_BASE_URL",g),console.log(`BASE URL: ${g}`)}}else{let g=o.get("TOOLNET_EMBEDDING_BASE_URL")||t.baseUrl||"",f=(await e.question(g?`BASE URL [${g}]: `:t.baseUrlRequired?"BASE URL: ":"BASE URL [optional]: ")).trim()||g;f&&o.set("TOOLNET_EMBEDDING_BASE_URL",C(f))}let s=o.get("TOOLNET_EMBEDDING_MODEL")||t.suggestedModel||"",c=(await e.question(s?`MODEL [${s}]: `:"MODEL: ")).trim()||s;c&&o.set("TOOLNET_EMBEDDING_MODEL",c)}function Cn(e,o){return o.id==="local"?!0:o.apiKeyRequired&&!e.get("TOOLNET_EMBEDDING_API_KEY")?.trim()||o.accountIdRequired&&!e.get("TOOLNET_EMBEDDING_ACCOUNT_ID")?.trim()||o.baseUrlRequired&&!e.get("TOOLNET_EMBEDDING_BASE_URL")?.trim()?!1:!!e.get("TOOLNET_EMBEDDING_MODEL")?.trim()}async function Co(e){let o=e.get("TOOLNET_EMBEDDING_PROVIDER")?.trim();if(console.log(""),console.log(`Testing embedding: ${Oe(o)}...`),o==="local")return console.log("\u2713 Local embedding ready"),console.log(""),!0;let t=e.get("TOOLNET_EMBEDDING_API_KEY")?.trim(),n=e.get("TOOLNET_EMBEDDING_MODEL")?.trim(),r=e.get("TOOLNET_EMBEDDING_BASE_URL")?.trim();try{if(!n)throw new Error("Embedding model is missing");if(o==="huggingface"){if(!t)throw new Error("API key is missing");let s=await fetch(`https://router.huggingface.co/hf-inference/models/${n}/pipeline/feature-extraction`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({inputs:["toolnet memory test"]})});if(!s.ok)throw new Error(`HTTP ${s.status}: ${await s.text()}`)}else if(o==="gemini"){if(!t)throw new Error("API key is missing");let s=n.replace(/^models\//,"");r=r||"https://generativelanguage.googleapis.com/v1beta";let i=await fetch(`${r.replace(/\/+$/,"")}/models/${encodeURIComponent(s)}:embedContent?key=${encodeURIComponent(t)}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:`models/${s}`,content:{parts:[{text:"toolnet memory test"}]}})});if(!i.ok)throw new Error(`HTTP ${i.status}: ${await i.text()}`)}else{if(!r)throw new Error("BASE URL is missing");let s=await fetch(`${r.replace(/\/+$/,"")}/embeddings`,{method:"POST",headers:{"content-type":"application/json",...t?{authorization:`Bearer ${t}`}:{}},body:JSON.stringify({model:n,input:["toolnet memory test"]})});if(!s.ok)throw new Error(`HTTP ${s.status}: ${await s.text()}`);let i=await s.json();if(!Array.isArray(i.data)||!Array.isArray(i.data[0]?.embedding))throw new Error("Invalid embedding response")}return console.log("\u2713 Embedding provider reachable"),console.log(`\u2713 Model: ${n}`),console.log(""),!0}catch(s){return console.log("\u2717 Embedding test failed"),console.log(` ${s instanceof Error?s.message:String(s)}`),console.log(""),!1}}async function Sn(e,o){let t=new Map(o);for(;;){let n=await No(e,o.get("TOOLNET_EMBEDDING_PROVIDER"));if(n==="back")return;if(await Nn(e,o,n),!Cn(o,n)){console.log(""),console.log("\u26A0 Embedding configuration is incomplete."),console.log(""),console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let i=(await e.question("Choose [1]: ")).trim()||"1";if(i==="2"){O(o);return}if(i==="3")continue;if(i==="4"){o.clear();for(let[c,a]of t)o.set(c,a);return}continue}if(await Co(o)){O(o),console.log(`\u2713 ${n.label} embedding configuration saved`),console.log(` ${p}`),console.log("");return}console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let s=(await e.question("Choose [1]: ")).trim()||"1";if(s==="2"){O(o);return}if(s!=="3"&&s==="4"){o.clear();for(let[i,c]of t)o.set(i,c);return}}}async function Rn(e,o){let t=o.get("TOOLNET_LLM_PROVIDER")?.trim();if(!t){console.log(""),console.log("\u26A0 Configure LLM first."),console.log("");return}if(t==="deepseek"||t==="groq"){console.log(""),console.log(`\u26A0 ${y(t)} is configured as LLM-only.`),console.log("Choose Embedding separately."),console.log("");return}o.set("TOOLNET_EMBEDDING_PROVIDER",t);let n=o.get("TOOLNET_LLM_API_KEY"),r=o.get("TOOLNET_LLM_BASE_URL"),s=o.get("TOOLNET_LLM_ACCOUNT_ID");n&&o.set("TOOLNET_EMBEDDING_API_KEY",n),r&&o.set("TOOLNET_EMBEDDING_BASE_URL",r),s&&o.set("TOOLNET_EMBEDDING_ACCOUNT_ID",s);let i="";t==="alibaba"?i="text-embedding-v4":t==="gemini"?i="gemini-embedding-001":t==="cloudflare"?i="@cf/baai/bge-base-en-v1.5":t==="huggingface"&&(i="sentence-transformers/all-MiniLM-L6-v2");let a=(await e.question(i?`EMBEDDING MODEL [${i}]: `:"EMBEDDING MODEL: ")).trim()||i;if(!a){console.log(""),console.log("\u26A0 Embedding model is required."),console.log("");return}if(o.set("TOOLNET_EMBEDDING_MODEL",a),!await Co(o)){let d=(await e.question("Save anyway? (y/N): ")).trim().toLowerCase();if(d!=="y"&&d!=="yes")return}O(o),console.log(""),console.log("\u2713 LLM credentials reused for Embedding"),console.log(`\u2713 Embedding model: ${a}`),console.log("")}function Q(e){return`TOOLNET_LLM_FALLBACK_${e}`}function Z(e,o){let t=Q(o);for(let n of["PROVIDER","API_KEY","BASE_URL","MODEL","ACCOUNT_ID"])e.delete(`${t}_${n}`)}function Lo(e,o){let t=Q(o),n=e.get(`${t}_PROVIDER`);if(!n)return"not configured";let r=e.get(`${t}_MODEL`);return`${y(n)}${r?` / ${r}`:""}`}async function To(e,o,t){console.log(""),console.log(`Fallback ${t}`),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let n=await fe(e,void 0);if(n==="back")return;let r=o.get("TOOLNET_LLM_PROVIDER");if(n===r){console.log(""),console.log("\u26A0 Fallback cannot be the same provider as Primary."),console.log("");return}let s=t===1?2:1,i=o.get(`${Q(s)}_PROVIDER`);if(n===i){console.log(""),console.log("\u26A0 This provider is already used by the other fallback."),console.log("");return}let c=I.find(_=>_.id===n);if(!c)return;let a=Q(t);if(Z(o,t),o.set(`${a}_PROVIDER`,n),c.accountIdRequired){let _=await e.question("ACCOUNT ID: ");_.trim()&&o.set(`${a}_ACCOUNT_ID`,_.trim())}if(c.apiKeyRequired||n==="custom"){let _=await b(e,c.apiKeyRequired?"API KEY: ":"API KEY [optional]: ");_.trim()&&o.set(`${a}_API_KEY`,_.trim())}if(n==="cloudflare"){let _=o.get(`${a}_ACCOUNT_ID`);_&&o.set(`${a}_BASE_URL`,`https://api.cloudflare.com/client/v4/accounts/${_}/ai`)}else{let _=c.baseUrl??"",pe=(await e.question(_?`BASE URL [${_}]: `:c.baseUrlRequired?"BASE URL: ":"BASE URL [optional]: ")).trim()||_;pe&&o.set(`${a}_BASE_URL`,C(pe))}let g=c.suggestedModel??"",f=(await e.question(g?`MODEL [${g}]: `:"MODEL: ")).trim()||g;if(!f){console.log(""),console.log("\u26A0 MODEL is required."),console.log(""),Z(o,t);return}o.set(`${a}_MODEL`,f),O(o),console.log(""),console.log(`\u2713 Fallback ${t} saved`),console.log(` ${y(n)} / ${f}`),console.log("")}async function hn(e,o){let t=o.get("TOOLNET_LLM_FALLBACK_COOLDOWN_MS")||"60000",n=o.get("TOOLNET_LLM_MAX_RETRIES")||"1";console.log(""),console.log("Fallback Policy"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let r=await e.question(`COOLDOWN MS [${t}]: `);if(r.trim()){let i=Number(r.trim());Number.isFinite(i)&&i>=0?o.set("TOOLNET_LLM_FALLBACK_COOLDOWN_MS",String(Math.floor(i))):console.log("\u26A0 Invalid cooldown; keeping previous value.")}let s=await e.question(`MAX RETRIES [${n}]: `);if(s.trim()){let i=Number(s.trim());Number.isFinite(i)&&i>=0&&i<=5?o.set("TOOLNET_LLM_MAX_RETRIES",String(Math.floor(i))):console.log("\u26A0 MAX RETRIES must be between 0 and 5.")}O(o),console.log(""),console.log("\u2713 Fallback policy saved"),console.log("")}async function Dn(e,o){for(;;){console.log(""),console.log("LLM Fallback"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),console.log(` Primary : ${o.get("TOOLNET_LLM_PROVIDER")?`${y(o.get("TOOLNET_LLM_PROVIDER"))} / ${o.get("TOOLNET_LLM_MODEL")||"model not configured"}`:"not configured"}`),console.log(` Fallback 1 : ${Lo(o,1)}`),console.log(` Fallback 2 : ${Lo(o,2)}`),console.log(` Cooldown : ${o.get("TOOLNET_LLM_FALLBACK_COOLDOWN_MS")||"60000"} ms`),console.log(` Retries : ${o.get("TOOLNET_LLM_MAX_RETRIES")||"1"}`),console.log(""),console.log(" 1. Configure Fallback 1"),console.log(" 2. Configure Fallback 2"),console.log(" 3. Remove Fallback 1"),console.log(" 4. Remove Fallback 2"),console.log(" 5. Retry / cooldown settings"),console.log(" 0. Back"),console.log("");let t=(await e.question("Choose: ")).trim();if(t==="0")return;if(t==="1"){await To(e,o,1);continue}if(t==="2"){await To(e,o,2);continue}if(t==="3"){Z(o,1),O(o),console.log(""),console.log("\u2713 Fallback 1 removed"),console.log("");continue}if(t==="4"){Z(o,2),O(o),console.log(""),console.log("\u2713 Fallback 2 removed"),console.log("");continue}if(t==="5"){await hn(e,o);continue}console.log(""),console.log("\u26A0 Invalid selection")}}async function bn(e,o){for(;;){console.log(""),console.log("AI Model"),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let t=o.get("TOOLNET_LLM_PROVIDER"),n=o.get("TOOLNET_EMBEDDING_PROVIDER");console.log(` LLM : ${t?`${y(t)} / ${o.get("TOOLNET_LLM_MODEL")||"model not configured"}`:"not configured"}`),console.log(` Embedding : ${n?`${Oe(n)} / ${o.get("TOOLNET_EMBEDDING_MODEL")||(n==="local"?"local hash":"model not configured")}`:"legacy/default"}`),console.log(""),console.log(" 1. Configure LLM"),console.log(" 2. Configure Embedding"),console.log(" 3. Use LLM provider credentials for Embedding"),console.log(" 4. Configure LLM Fallbacks"),console.log(" 0. Back"),console.log("");let r=(await e.question("Choose: ")).trim();if(r==="0")return;if(r==="1"){await Pn(e,o);continue}if(r==="2"){await Sn(e,o);continue}if(r==="3"){await Rn(e,o);continue}if(r==="4"){await Dn(e,o);continue}console.log(""),console.log("\u26A0 Invalid selection")}}async function Pn(e,o){let t=new Map(o);for(;;){let n=await fe(e,Io(o));if(n==="back")return;let r=I.find(c=>c.id===n);if(!r)continue;if(await yn(e,o,r),!Tn(o,r)){console.log(""),console.log("\u26A0 AI configuration is incomplete."),console.log(""),console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let c=(await e.question("Choose [1]: ")).trim()||"1";if(c==="2"){O(o),console.log(""),console.log("\u26A0 AI configuration saved without validation"),console.log(` ${p}`),console.log("");return}if(c==="3")continue;if(c==="4"){o.clear();for(let[a,g]of t)o.set(a,g);console.log(""),console.log("AI changes cancelled."),console.log("");return}continue}if((await In(o)).ok){O(o),console.log(`\u2713 ${r.label} configuration saved`),console.log(` ${p}`),console.log("");return}console.log(" 1. Retry"),console.log(" 2. Save anyway"),console.log(" 3. Choose another provider"),console.log(" 4. Cancel"),console.log("");let i=(await e.question("Choose [1]: ")).trim()||"1";if(i==="2"){O(o),console.log(""),console.log("\u26A0 AI configuration saved even though provider test failed"),console.log(` ${p}`),console.log("");return}if(i!=="3"&&i==="4"){o.clear();for(let[c,a]of t)o.set(c,a);console.log(""),console.log("AI changes cancelled."),console.log("");return}}}function wn(){try{let o=de().filter(t=>t.installed);if(o.length===0)return;console.log(""),console.log("Automatic AI memory");for(let t of o){let n=t.agent==="agy"?"Agy / Antigravity":t.agent==="opencode"?"OpenCode":t.agent==="codex"?"Codex":t.agent;console.log(` \u2713 ${n}`)}}catch{}}function E(e,...o){for(let t of o){let n=e.get(t)?.trim();if(n)return n}}function m(e,o,t){t&&!e.get(o)?.trim()&&e.set(o,t)}function Un(e){let o=!1,t=JSON.stringify([...e.entries()]);if(!e.get("TOOLNET_LLM_PROVIDER")?.trim()){let s;E(e,"GROQ_API_KEY")?s="groq":E(e,"DEEPSEEK_API_KEY")?s="deepseek":E(e,"NVIDIA_API_KEY","NVIDIA_NIM_API_KEY")?s="nvidia":E(e,"OPENROUTER_API_KEY")?s="openrouter":E(e,"ALIBABA_API_KEY","DASHSCOPE_API_KEY")?s="alibaba":E(e,"GEMINI_API_KEY","GOOGLE_API_KEY")?s="gemini":E(e,"CLOUDFLARE_API_TOKEN")&&E(e,"CLOUDFLARE_ACCOUNT_ID")?s="cloudflare":E(e,"HF_TOKEN")?s="huggingface":E(e,"OLLAMA_MODEL","OLLAMA_BASE_URL")?s="ollama":E(e,"OPENAI_API_KEY","MODEL_API_KEY")&&(s="openai-compatible"),s&&e.set("TOOLNET_LLM_PROVIDER",s)}switch(e.get("TOOLNET_LLM_PROVIDER")?.trim()){case"groq":m(e,"TOOLNET_LLM_API_KEY",E(e,"GROQ_API_KEY")),m(e,"TOOLNET_LLM_BASE_URL",E(e,"GROQ_BASE_URL")||"https://api.groq.com/openai/v1"),m(e,"TOOLNET_LLM_MODEL",E(e,"GROQ_MODEL"));break;case"deepseek":m(e,"TOOLNET_LLM_API_KEY",E(e,"DEEPSEEK_API_KEY")),m(e,"TOOLNET_LLM_BASE_URL",E(e,"DEEPSEEK_BASE_URL")||"https://api.deepseek.com"),m(e,"TOOLNET_LLM_MODEL",E(e,"DEEPSEEK_MODEL")||"deepseek-v4-flash");break;case"nvidia":m(e,"TOOLNET_LLM_API_KEY",E(e,"NVIDIA_API_KEY","NVIDIA_NIM_API_KEY")),m(e,"TOOLNET_LLM_BASE_URL",E(e,"NVIDIA_BASE_URL","NVIDIA_NIM_BASE_URL")||"https://integrate.api.nvidia.com/v1"),m(e,"TOOLNET_LLM_MODEL",E(e,"NVIDIA_MODEL","NVIDIA_NIM_MODEL"));break;case"openrouter":m(e,"TOOLNET_LLM_API_KEY",E(e,"OPENROUTER_API_KEY")),m(e,"TOOLNET_LLM_BASE_URL",E(e,"OPENROUTER_BASE_URL")||"https://openrouter.ai/api/v1"),m(e,"TOOLNET_LLM_MODEL",E(e,"OPENROUTER_MODEL"));break;case"alibaba":m(e,"TOOLNET_LLM_API_KEY",E(e,"ALIBABA_API_KEY","DASHSCOPE_API_KEY")),m(e,"TOOLNET_LLM_BASE_URL",E(e,"ALIBABA_BASE_URL","DASHSCOPE_BASE_URL")),m(e,"TOOLNET_LLM_MODEL",E(e,"ALIBABA_MODEL","DASHSCOPE_MODEL"));break;case"gemini":m(e,"TOOLNET_LLM_API_KEY",E(e,"GEMINI_API_KEY","GOOGLE_API_KEY")),m(e,"TOOLNET_LLM_BASE_URL",E(e,"GEMINI_BASE_URL")||"https://generativelanguage.googleapis.com/v1beta"),m(e,"TOOLNET_LLM_MODEL",E(e,"GEMINI_MODEL"));break;case"huggingface":m(e,"TOOLNET_LLM_API_KEY",E(e,"HF_TOKEN")),m(e,"TOOLNET_LLM_BASE_URL",E(e,"HF_INFERENCE_BASE_URL")||"https://router.huggingface.co/v1"),m(e,"TOOLNET_LLM_MODEL",E(e,"HF_LLM_MODEL","HF_MODEL"));break;case"ollama":m(e,"TOOLNET_LLM_API_KEY",E(e,"OLLAMA_API_KEY")),m(e,"TOOLNET_LLM_BASE_URL",E(e,"OLLAMA_BASE_URL")||"http://127.0.0.1:11434/v1"),m(e,"TOOLNET_LLM_MODEL",E(e,"OLLAMA_MODEL"));break;case"cloudflare":m(e,"TOOLNET_LLM_API_KEY",E(e,"CLOUDFLARE_API_TOKEN")),m(e,"TOOLNET_LLM_ACCOUNT_ID",E(e,"CLOUDFLARE_ACCOUNT_ID")),m(e,"TOOLNET_LLM_MODEL",E(e,"CLOUDFLARE_MODEL"));break;case"openai-compatible":m(e,"TOOLNET_LLM_API_KEY",E(e,"OPENAI_API_KEY","MODEL_API_KEY")),m(e,"TOOLNET_LLM_BASE_URL",E(e,"OPENAI_BASE_URL","MODEL_BASE_URL")),m(e,"TOOLNET_LLM_MODEL",E(e,"OPENAI_MODEL","MODEL_NAME"));break}!e.get("TOOLNET_EMBEDDING_PROVIDER")?.trim()&&E(e,"HF_TOKEN")&&(e.set("TOOLNET_EMBEDDING_PROVIDER","huggingface"),m(e,"TOOLNET_EMBEDDING_API_KEY",E(e,"HF_TOKEN")),m(e,"TOOLNET_EMBEDDING_MODEL",E(e,"HF_EMBEDDING_MODEL")||"sentence-transformers/all-MiniLM-L6-v2"));let r=JSON.stringify([...e.entries()]);return o=t!==r,o}function X(e,o="not configured"){return e?.trim()||o}function Kn(e){let o=F(N(e)),t=e.get("TOOLNET_LLM_PROVIDER"),n=e.get("TOOLNET_LLM_MODEL"),r=e.get("TOOLNET_EMBEDDING_PROVIDER"),s=e.get("TOOLNET_EMBEDDING_MODEL"),i=e.get("TOOLNET_LLM_FALLBACK_1_PROVIDER"),c=e.get("TOOLNET_LLM_FALLBACK_2_PROVIDER");console.log(""),console.log("TOOLNET MEMORY READY"),console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"),console.log(`Storage : ${o}`),console.log(`LLM : ${t?`${y(t)} / ${X(n)}`:"not configured"}`),console.log(`Fallback 1 : ${i?`${y(i)} / ${X(e.get("TOOLNET_LLM_FALLBACK_1_MODEL"))}`:"none"}`),console.log(`Fallback 2 : ${c?`${y(c)} / ${X(e.get("TOOLNET_LLM_FALLBACK_2_MODEL"))}`:"none"}`),console.log(`Embedding : ${r?`${r==="local"?"Local / Hash":Oe(r)} / ${X(s,r==="local"?"local hash":"not configured")}`:"legacy/default"}`),console.log(""),console.log(`Config : ${p}`),console.log(`Permissions: ${A.statSync(p).mode.toString(8).slice(-3)}`),console.log(""),console.log("Secrets : hidden"),console.log("Config mode: canonical TOOLNET_*"),console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")}function So(e){Un(e),e.has("TOOLNET_LLM_FALLBACK_COOLDOWN_MS")||e.set("TOOLNET_LLM_FALLBACK_COOLDOWN_MS","60000"),e.has("TOOLNET_LLM_MAX_RETRIES")||e.set("TOOLNET_LLM_MAX_RETRIES","1"),e.has("MEMORY_STORAGE_PROVIDER")||e.set("MEMORY_STORAGE_PROVIDER",N(e)),e.has("MEMORY_LOCAL_CACHE_MB")||e.set("MEMORY_LOCAL_CACHE_MB","200"),e.has("MEMORY_AUTO_CAPTURE")||e.set("MEMORY_AUTO_CAPTURE","true"),e.has("MEMORY_AUTO_RETRIEVE")||e.set("MEMORY_AUTO_RETRIEVE","true"),e.has("MEMORY_AUTO_SUMMARIZE")||e.set("MEMORY_AUTO_SUMMARIZE","true"),e.has("MEMORY_AUTO_SYNC")||e.set("MEMORY_AUTO_SYNC","true"),e.has("MEMORY_MAX_CANDIDATES")||e.set("MEMORY_MAX_CANDIDATES","50"),e.has("MEMORY_RERANK_TOP")||e.set("MEMORY_RERANK_TOP","10"),e.has("MEMORY_FINAL_CONTEXT")||e.set("MEMORY_FINAL_CONTEXT","5"),e.has("MEMORY_TOKEN_BUDGET")||e.set("MEMORY_TOKEN_BUDGET","2000"),e.has("TOOLNET_SESSION_LEARNING")||e.set("TOOLNET_SESSION_LEARNING","1"),e.has("TOOLNET_WORK_CONTINUITY")||e.set("TOOLNET_WORK_CONTINUITY","1"),e.has("TOOLNET_SEMANTIC_CONTINUITY")||e.set("TOOLNET_SEMANTIC_CONTINUITY","1"),e.has("TOOLNET_SMART_HANDOFF")||e.set("TOOLNET_SMART_HANDOFF","1")}async function kn(e,o){So(e),o||O(e),console.log("TOOLNET MEMORY SETUP"),console.log(""),console.log("Interactive terminal not detected."),console.log(`Config: ${p}`),console.log(`Storage: ${F(N(e))}`),console.log(""),console.log("Run from an interactive terminal to configure providers:"),console.log(" toolnet-memory setup")}async function Bn(){let e=A.existsSync(p),o=e?on(A.readFileSync(p,"utf8")):new Map,t=new Map(o);if(So(t),!T.isTTY||!k.isTTY){await kn(t,e);return}let n=zt.createInterface({input:T,output:k}),r=!1;try{for(;;){gn(),dn(t);let s=await En(n);if(s==="storage"){let i=JSON.stringify([...t.entries()]);await pn(n,t),r=r||i!==JSON.stringify([...t.entries()]);continue}if(s==="ai"){let i=JSON.stringify([...t.entries()]);await bn(n,t),r=r||i!==JSON.stringify([...t.entries()]);continue}if(s==="exit"){if(!r){console.log(""),console.log("No changes made.");return}console.log("");let i=(await n.question("Discard unsaved changes? (y/N): ")).trim().toLowerCase();if(i==="y"||i==="yes"){console.log(""),console.log("Changes discarded.");return}continue}O(t),yo(t)||(console.log(""),console.log("\u26A0 Storage configuration is incomplete.")),wn(),Kn(t),console.log(""),console.log("Validate:"),console.log(" toolnet-memory provider:status"),console.log(" toolnet-memory provider:test"),console.log(" toolnet-memory doctor"),console.log("");return}}finally{n.close()}}Bn().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});