toolnet-memory 0.3.12 → 0.3.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolnet-memory",
3
- "version": "0.3.12",
3
+ "version": "0.3.13",
4
4
  "description": "Persistent project memory, work continuity, and code intelligence for AI coding agents.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -43,8 +43,6 @@
43
43
  "start": "node dist/index.js",
44
44
  "test": "vitest run",
45
45
  "storage:test": "tsx src/storage/test-connection.ts",
46
- "embedding:test": "tsx src/embeddings/test-connection.ts",
47
- "vector:persist:test": "tsx src/retrieval/vector/test-persistence.ts",
48
46
  "code:index:test": "tsx src/code-intelligence/test-index.ts",
49
47
  "code:incremental:test": "tsx src/code-intelligence/test-incremental.ts",
50
48
  "mcp": "tsx src/mcp/bootstrap.ts",
@@ -1,2 +0,0 @@
1
- var v=[{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 m(e){let r=v.find(n=>n.id===e);if(!r)throw new Error(`Unsupported AI provider: ${e}`);return r}function _(e){return v.some(r=>r.id===e)}function o(e){return process.env[e]?.trim()||void 0}function t(...e){return e.find(r=>!!r?.trim())}function y(){if(o("GROQ_API_KEY"))return"groq";if(o("DEEPSEEK_API_KEY"))return"deepseek";if(o("NVIDIA_API_KEY")||o("NVIDIA_NIM_API_KEY"))return"nvidia";if(o("OPENROUTER_API_KEY"))return"openrouter";if(o("ALIBABA_API_KEY")||o("DASHSCOPE_API_KEY"))return"alibaba";if(o("GEMINI_API_KEY")||o("GOOGLE_API_KEY"))return"gemini";if(o("CLOUDFLARE_API_TOKEN")&&o("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(o("HF_TOKEN"))return"huggingface";if(o("OLLAMA_MODEL")||o("OLLAMA_BASE_URL"))return"ollama"}function K(){let e=o("TOOLNET_LLM_PROVIDER");return e&&_(e)?e:y()??"openai-compatible"}function U(e){let r=m(e);switch(e){case"alibaba":return{provider:e,apiKey:t(o("ALIBABA_API_KEY"),o("DASHSCOPE_API_KEY")),baseUrl:t(o("ALIBABA_BASE_URL"),o("DASHSCOPE_BASE_URL"),r.defaultBaseUrl),model:t(o("ALIBABA_MODEL"),o("DASHSCOPE_MODEL"))};case"openrouter":return{provider:e,apiKey:o("OPENROUTER_API_KEY"),baseUrl:t(o("OPENROUTER_BASE_URL"),r.defaultBaseUrl),model:o("OPENROUTER_MODEL")};case"groq":return{provider:e,apiKey:o("GROQ_API_KEY"),baseUrl:t(o("GROQ_BASE_URL"),r.defaultBaseUrl),model:o("GROQ_MODEL")};case"deepseek":return{provider:e,apiKey:o("DEEPSEEK_API_KEY"),baseUrl:t(o("DEEPSEEK_BASE_URL"),r.defaultBaseUrl),model:t(o("DEEPSEEK_MODEL"),r.defaultModel)};case"nvidia":return{provider:e,apiKey:t(o("NVIDIA_API_KEY"),o("NVIDIA_NIM_API_KEY")),baseUrl:t(o("NVIDIA_BASE_URL"),o("NVIDIA_NIM_BASE_URL"),r.defaultBaseUrl),model:t(o("NVIDIA_MODEL"),o("NVIDIA_NIM_MODEL"),r.defaultModel)};case"gemini":return{provider:e,apiKey:t(o("GEMINI_API_KEY"),o("GOOGLE_API_KEY")),baseUrl:t(o("GEMINI_BASE_URL"),r.defaultBaseUrl),model:o("GEMINI_MODEL")};case"huggingface":return{provider:e,apiKey:o("HF_TOKEN"),baseUrl:t(o("HF_INFERENCE_BASE_URL"),r.defaultBaseUrl),model:t(o("HF_LLM_MODEL"),o("HF_MODEL"))};case"ollama":return{provider:e,apiKey:o("OLLAMA_API_KEY"),baseUrl:t(o("OLLAMA_BASE_URL"),r.defaultBaseUrl),model:o("OLLAMA_MODEL")};case"cloudflare":return{provider:e,accountId:o("CLOUDFLARE_ACCOUNT_ID"),apiKey:o("CLOUDFLARE_API_TOKEN"),baseUrl:o("CLOUDFLARE_AI_BASE_URL"),model:o("CLOUDFLARE_MODEL")};case"custom":return{provider:e,apiKey:o("CUSTOM_AI_API_KEY"),baseUrl:o("CUSTOM_AI_BASE_URL"),model:o("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:t(o("OPENAI_API_KEY"),o("MODEL_API_KEY")),baseUrl:t(o("OPENAI_BASE_URL"),o("MODEL_BASE_URL")),model:t(o("OPENAI_MODEL"),o("MODEL_NAME"))}}}function B(){let e=o("TOOLNET_LLM_PROVIDER"),r=e&&_(e)?e:K(),n=m(r),i=U(r);return{provider:r,apiKey:t(o("TOOLNET_LLM_API_KEY"),i.apiKey),baseUrl:t(o("TOOLNET_LLM_BASE_URL"),i.baseUrl,n.defaultBaseUrl),model:t(o("TOOLNET_LLM_MODEL"),i.model,n.defaultModel),accountId:t(o("TOOLNET_LLM_ACCOUNT_ID"),i.accountId)}}function S(){let e=o("TOOLNET_EMBEDDING_PROVIDER");return e==="local"?"local":e&&_(e)?e:o("HF_TOKEN")||o("HF_EMBEDDING_MODEL")?"huggingface":"local"}function x(){let e=S();if(e==="local")return{provider:"local",model:t(o("TOOLNET_EMBEDDING_MODEL"),o("LOCAL_EMBEDDING_MODEL"))};let r=m(e),n,i,l,s;switch(e){case"huggingface":n=o("HF_TOKEN"),i=o("HF_INFERENCE_BASE_URL"),l=o("HF_EMBEDDING_MODEL");break;case"openai-compatible":n=o("OPENAI_API_KEY"),i=o("OPENAI_BASE_URL"),l=o("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":n=o("CLOUDFLARE_API_TOKEN"),i=o("CLOUDFLARE_AI_BASE_URL"),l=o("CLOUDFLARE_EMBEDDING_MODEL"),s=o("CLOUDFLARE_ACCOUNT_ID");break;default:n=U(e).apiKey,i=U(e).baseUrl,l=o(`${e.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let E=t(o("TOOLNET_EMBEDDING_ACCOUNT_ID"),s),N=t(o("TOOLNET_EMBEDDING_BASE_URL"),i,r.defaultBaseUrl),T=e==="cloudflare"&&!N&&E?`https://api.cloudflare.com/client/v4/accounts/${E}/ai/v1`:N;return{provider:e,apiKey:t(o("TOOLNET_EMBEDDING_API_KEY"),n),baseUrl:T,model:t(o("TOOLNET_EMBEDDING_MODEL"),l),accountId:E}}function O(){let e=B(),r=x();return{llm:e,embedding:r,legacy:{llm:!o("TOOLNET_LLM_PROVIDER")&&!!y(),embedding:!o("TOOLNET_EMBEDDING_PROVIDER")&&!!(o("HF_TOKEN")||o("HF_EMBEDDING_MODEL"))}}}import u from"node:fs";import k from"node:os";import R from"node:path";var G={spinner:["\xB7","\u2722","\u2733","\u2736","\u273B","\u273D"],barFilled:"\u2588",barEmpty:"\u2591",phaseDone:"\u25C6",phaseActive:"\u25C7",rail:"\u2502",branch:"\u251C",corner:"\u2514",dash:"\u2014"},F={spinner:[".","*","+","x","*","+"],barFilled:"#",barEmpty:"-",phaseDone:"[OK]",phaseActive:"[>>]",rail:"|",branch:"|",corner:"\\",dash:"-"};function w(){if(process.env.TOOLNET_ASCII==="1")return!1;if(process.env.TOOLNET_UNICODE==="1")return!0;if(process.platform==="win32"){let e=process.env.TERM_PROGRAM,r=process.env.WT_SESSION,n=process.env.VSCODE_PID,i=process.env.ConEmuPID;return!!(r||n||i||e==="vscode")}return process.env.TERM!=="linux"}var M;function D(){return M||(M=w()?G:F),M}var a={reset:"\x1B[0m",green:"\x1B[32m",cyan:"\x1B[36m",red:"\x1B[31m",yellow:"\x1B[33m",amber:"\x1B[38;5;214m",white:"\x1B[97m",dim:"\x1B[2m",bold:"\x1B[1m"};function $(e){return e.noColor||process.env.NO_COLOR?!1:e.tty??process.stdout.isTTY??!1}function c(e,r,n){return $(n)?`${r}${e}${a.reset}`:e}function d(e,r){return c(e,a.dim,r)}function Y(e,r){return c(e,a.bold,r)}function A(e,r){return c(e,a.cyan,r)}function H(e,r){return c(e,a.green,r)}function V(e,r){return c(e,a.red,r)}function q(e,r){return c(e,a.white,r)}function L(e,r,n){let i=D(),l=r?` ${d(`v${r}`,n)}`:"";return`${A(i.phaseDone,n)} ${e}${l}`}function I(e,r){return Y(e,r)}function b(e,r,n,i){let l=" ".repeat(Math.max(0,n-e.length));return` ${A(e,i)}${l} ${r}`}function p(e,r,n,i){let l=" ".repeat(Math.max(0,n-e.length));return` ${d(e,i)}${l} ${q(r,i)}`}function P(e){let r=D();return H(r.phaseDone,e)}function C(e){return V("\u2717",e)}function f(e){return{tty:e.tty,noColor:e.noColor}}var h=R.join(k.homedir(),".config","toolnet-memory"),g=R.join(h,".env");function j(){u.mkdirSync(h,{recursive:!0,mode:448}),u.existsSync(g)||u.writeFileSync(g,"",{encoding:"utf8",mode:384})}function W(){return j(),u.readFileSync(g,"utf8").split(/\r?\n/)}function Q(e,r){let n=W(),i=!1,l=n.map(s=>s.trim().startsWith(`${e}=`)?(i=!0,`${e}=${r}`):s);i||(l.length&&l[l.length-1]!==""&&l.push(""),l.push(`${e}=${r}`)),u.writeFileSync(g,l.join(`
2
- `),{encoding:"utf8",mode:384}),u.chmodSync(g,384)}async function X(e){let r=O(),n=f(e);console.log(""),console.log(L("AI Model",void 0,n)),console.log(""),console.log(I("CURRENT",n)),console.log(p("Provider",r.llm.provider,8,n)),console.log(p("Model",r.llm.model??"not set",8,n)),console.log(""),console.log(I("COMMANDS",n)),console.log(b("model list","List available models",15,n)),console.log(b("model set <model>","Change model",15,n)),console.log(b("model status","Show current model",15,n)),console.log("")}async function z(e){let r=O(),n=f(e);console.log(""),console.log(L("Available Models",void 0,n)),console.log(""),console.log(I("CURRENT MODEL",n)),console.log(` ${A("\u25CF",n)} ${r.llm.model??"not set"}`),console.log(""),console.log(d(" Model discovery not available.",n)),console.log(d(" Use `model set <model>` to change the model.",n)),console.log("")}async function J(e,r){let n=O(),i=f(r);console.log(""),console.log(L("Change Model",void 0,i)),console.log("");try{Q("TOOLNET_LLM_MODEL",e),console.log(P(i)+" Model updated"),console.log(""),console.log(p("Provider",n.llm.provider,8,i)),console.log(p("Model",e,8,i)),console.log("")}catch(l){console.log(C(i)+" Failed to update model"),console.log(""),console.log(d(` ${l instanceof Error?l.message:String(l)}`,i)),console.log(""),process.exitCode=1}}async function Z(){let e=process.argv.slice(2),r=e[0],n={tty:process.stdout.isTTY,noColor:process.env.NO_COLOR!==void 0||e.includes("--no-color")};if(!r||r==="status"){await X(n);return}if(r==="list"){await z(n);return}if(r==="set"){let l=e[1];if(!l){let s=f(n);console.log(""),console.log(C(s)+" Missing model name"),console.log(""),console.log("Usage: toolnet-memory model set <model>"),console.log(""),process.exitCode=1;return}await J(l,n);return}let i=f(n);console.log(""),console.log(C(i)+` Unknown subcommand: ${r}`),console.log(""),console.log("Available commands:"),console.log(" model"),console.log(" model status"),console.log(" model list"),console.log(" model set <model>"),console.log(""),process.exitCode=1}Z().catch(e=>{console.error(""),console.error(e instanceof Error?e.message:String(e)),console.error(""),process.exitCode=1});
@@ -1,6 +0,0 @@
1
- import"dotenv/config";var h=[{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 g(e){let r=h.find(t=>t.id===e);if(!r)throw new Error(`Unsupported AI provider: ${e}`);return r}function E(e){return h.some(r=>r.id===e)}function o(e){return process.env[e]?.trim()||void 0}function a(...e){return e.find(r=>!!r?.trim())}function T(){if(o("GROQ_API_KEY"))return"groq";if(o("DEEPSEEK_API_KEY"))return"deepseek";if(o("NVIDIA_API_KEY")||o("NVIDIA_NIM_API_KEY"))return"nvidia";if(o("OPENROUTER_API_KEY"))return"openrouter";if(o("ALIBABA_API_KEY")||o("DASHSCOPE_API_KEY"))return"alibaba";if(o("GEMINI_API_KEY")||o("GOOGLE_API_KEY"))return"gemini";if(o("CLOUDFLARE_API_TOKEN")&&o("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(o("HF_TOKEN"))return"huggingface";if(o("OLLAMA_MODEL")||o("OLLAMA_BASE_URL"))return"ollama"}function C(){let e=o("TOOLNET_LLM_PROVIDER");return e&&E(e)?e:T()??"openai-compatible"}function y(e){let r=g(e);switch(e){case"alibaba":return{provider:e,apiKey:a(o("ALIBABA_API_KEY"),o("DASHSCOPE_API_KEY")),baseUrl:a(o("ALIBABA_BASE_URL"),o("DASHSCOPE_BASE_URL"),r.defaultBaseUrl),model:a(o("ALIBABA_MODEL"),o("DASHSCOPE_MODEL"))};case"openrouter":return{provider:e,apiKey:o("OPENROUTER_API_KEY"),baseUrl:a(o("OPENROUTER_BASE_URL"),r.defaultBaseUrl),model:o("OPENROUTER_MODEL")};case"groq":return{provider:e,apiKey:o("GROQ_API_KEY"),baseUrl:a(o("GROQ_BASE_URL"),r.defaultBaseUrl),model:o("GROQ_MODEL")};case"deepseek":return{provider:e,apiKey:o("DEEPSEEK_API_KEY"),baseUrl:a(o("DEEPSEEK_BASE_URL"),r.defaultBaseUrl),model:a(o("DEEPSEEK_MODEL"),r.defaultModel)};case"nvidia":return{provider:e,apiKey:a(o("NVIDIA_API_KEY"),o("NVIDIA_NIM_API_KEY")),baseUrl:a(o("NVIDIA_BASE_URL"),o("NVIDIA_NIM_BASE_URL"),r.defaultBaseUrl),model:a(o("NVIDIA_MODEL"),o("NVIDIA_NIM_MODEL"),r.defaultModel)};case"gemini":return{provider:e,apiKey:a(o("GEMINI_API_KEY"),o("GOOGLE_API_KEY")),baseUrl:a(o("GEMINI_BASE_URL"),r.defaultBaseUrl),model:o("GEMINI_MODEL")};case"huggingface":return{provider:e,apiKey:o("HF_TOKEN"),baseUrl:a(o("HF_INFERENCE_BASE_URL"),r.defaultBaseUrl),model:a(o("HF_LLM_MODEL"),o("HF_MODEL"))};case"ollama":return{provider:e,apiKey:o("OLLAMA_API_KEY"),baseUrl:a(o("OLLAMA_BASE_URL"),r.defaultBaseUrl),model:o("OLLAMA_MODEL")};case"cloudflare":return{provider:e,accountId:o("CLOUDFLARE_ACCOUNT_ID"),apiKey:o("CLOUDFLARE_API_TOKEN"),baseUrl:o("CLOUDFLARE_AI_BASE_URL"),model:o("CLOUDFLARE_MODEL")};case"custom":return{provider:e,apiKey:o("CUSTOM_AI_API_KEY"),baseUrl:o("CUSTOM_AI_BASE_URL"),model:o("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:a(o("OPENAI_API_KEY"),o("MODEL_API_KEY")),baseUrl:a(o("OPENAI_BASE_URL"),o("MODEL_BASE_URL")),model:a(o("OPENAI_MODEL"),o("MODEL_NAME"))}}}function F(){let e=o("TOOLNET_LLM_PROVIDER"),r=e&&E(e)?e:C(),t=g(r),i=y(r);return{provider:r,apiKey:a(o("TOOLNET_LLM_API_KEY"),i.apiKey),baseUrl:a(o("TOOLNET_LLM_BASE_URL"),i.baseUrl,t.defaultBaseUrl),model:a(o("TOOLNET_LLM_MODEL"),i.model,t.defaultModel),accountId:a(o("TOOLNET_LLM_ACCOUNT_ID"),i.accountId)}}function H(){let e=o("TOOLNET_EMBEDDING_PROVIDER");return e==="local"?"local":e&&E(e)?e:o("HF_TOKEN")||o("HF_EMBEDDING_MODEL")?"huggingface":"local"}function Y(){let e=H();if(e==="local")return{provider:"local",model:a(o("TOOLNET_EMBEDDING_MODEL"),o("LOCAL_EMBEDDING_MODEL"))};let r=g(e),t,i,n,s;switch(e){case"huggingface":t=o("HF_TOKEN"),i=o("HF_INFERENCE_BASE_URL"),n=o("HF_EMBEDDING_MODEL");break;case"openai-compatible":t=o("OPENAI_API_KEY"),i=o("OPENAI_BASE_URL"),n=o("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":t=o("CLOUDFLARE_API_TOKEN"),i=o("CLOUDFLARE_AI_BASE_URL"),n=o("CLOUDFLARE_EMBEDDING_MODEL"),s=o("CLOUDFLARE_ACCOUNT_ID");break;default:t=y(e).apiKey,i=y(e).baseUrl,n=o(`${e.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let l=a(o("TOOLNET_EMBEDDING_ACCOUNT_ID"),s),d=a(o("TOOLNET_EMBEDDING_BASE_URL"),i,r.defaultBaseUrl),m=e==="cloudflare"&&!d&&l?`https://api.cloudflare.com/client/v4/accounts/${l}/ai/v1`:d;return{provider:e,apiKey:a(o("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:m,model:a(o("TOOLNET_EMBEDDING_MODEL"),n),accountId:l}}function u(){let e=F(),r=Y();return{llm:e,embedding:r,legacy:{llm:!o("TOOLNET_LLM_PROVIDER")&&!!T(),embedding:!o("TOOLNET_EMBEDDING_PROVIDER")&&!!(o("HF_TOKEN")||o("HF_EMBEDDING_MODEL"))}}}function N(e=C()){let r=u().llm;if(e===r.provider)return{id:e,apiKey:r.apiKey,baseUrl:r.baseUrl,model:r.model,accountId:r.accountId};let t=y(e);return{id:e,apiKey:t.apiKey,baseUrl:t.baseUrl,model:t.model,accountId:t.accountId}}var U=class extends Error{status;constructor(r,t){super(r),this.name="AiHttpError",this.status=t}};async function f(e,r,t=3e4){let i=new AbortController,n=setTimeout(()=>i.abort(),t);n.unref?.();try{let s=await fetch(e,{...r,signal:i.signal}),l=await s.text();if(!s.ok){let d=l;try{let m=JSON.parse(l);d=m.error?.message??m.message??l}catch{}throw new U(d||`HTTP ${s.status}`,s.status)}return l.trim()?JSON.parse(l):{}}finally{clearTimeout(n)}}function A(e,r){return`${e.replace(/\/+$/,"")}/${r.replace(/^\/+/,"")}`}var v=class{constructor(r){this.config=r}config;id="cloudflare";model(){let r=this.config.model?.trim();if(!r)throw new Error("cloudflare: MODEL is not configured");return r}async generate(r){let t=this.config.accountId?.trim(),i=this.config.apiKey?.trim();if(!t)throw new Error("cloudflare: ACCOUNT ID is not configured");if(!i)throw new Error("cloudflare: API TOKEN is not configured");let n=this.model(),l=`${(this.config.baseUrl?.trim()||`https://api.cloudflare.com/client/v4/accounts/${t}/ai/run`).replace(/\/+$/,"")}/${n}`,d=await f(l,{method:"POST",headers:{authorization:`Bearer ${i}`,"content-type":"application/json",...this.config.headers},body:JSON.stringify({messages:r.messages,temperature:r.temperature,max_tokens:r.maxTokens})}),m=d.result?.response?.trim();if(!m)throw new Error(d.errors?.[0]?.message??"cloudflare: empty model response");return{text:m,provider:"cloudflare",model:n}}async healthCheck(){let r=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()-r}}catch(t){return{ok:!1,provider:"cloudflare",model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-r}}}};var _=class{constructor(r){this.config=r}config;id="gemini";model(){let r=this.config.model?.trim();if(!r)throw new Error("gemini: MODEL is not configured");return r.replace(/^models\//,"")}async generate(r){let t=this.config.apiKey?.trim();if(!t)throw new Error("gemini: API KEY is not configured");let i=this.config.baseUrl?.trim()||"https://generativelanguage.googleapis.com/v1beta",n=this.model(),s=r.messages.filter(p=>p.role==="system"),l=r.messages.filter(p=>p.role!=="system").map(p=>({role:p.role==="assistant"?"model":"user",parts:[{text:p.content}]})),d=`${A(i,`models/${encodeURIComponent(n)}:generateContent`)}?key=${encodeURIComponent(t)}`,m=await f(d,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...s.length?{systemInstruction:{parts:[{text:s.map(p=>p.content).join(`
2
-
3
- `)}]}}:{},contents:l,generationConfig:{temperature:r.temperature,maxOutputTokens:r.maxTokens}})}),D=m.candidates?.[0]?.content?.parts?.map(p=>p.text??"").join("").trim();if(!D)throw new Error("gemini: empty model response");return{text:D,provider:"gemini",model:n,usage:m.usageMetadata?{inputTokens:m.usageMetadata.promptTokenCount,outputTokens:m.usageMetadata.candidatesTokenCount,totalTokens:m.usageMetadata.totalTokenCount}:void 0}}async healthCheck(){let r=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()-r}}catch(t){return{ok:!1,provider:"gemini",model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-r}}}};var O=class{constructor(r){this.config=r;this.id=r.id}config;id;baseUrl(){let r=this.config.baseUrl?.trim();if(!r)throw new Error(`${this.id}: BASE URL is not configured`);return r}model(){let r=this.config.model?.trim();if(!r)throw new Error(`${this.id}: MODEL is not configured`);return r}headers(){let r={"content-type":"application/json",...this.config.headers};return this.config.apiKey&&(r.authorization=`Bearer ${this.config.apiKey}`),r}async generate(r){let t=this.model(),i=await f(A(this.baseUrl(),"chat/completions"),{method:"POST",headers:this.headers(),body:JSON.stringify({model:t,messages:r.messages,temperature:r.temperature,max_tokens:r.maxTokens,...this.id==="alibaba"?{enable_thinking:!1}:{}})}),n=i.choices?.[0]?.message?.content?.trim();if(!n)throw new Error(`${this.id}: empty model response`);return{text:n,provider:this.id,model:t,usage:i.usage?{inputTokens:i.usage.prompt_tokens,outputTokens:i.usage.completion_tokens,totalTokens:i.usage.total_tokens}:void 0}}async healthCheck(){let r=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()-r}}catch(t){return{ok:!1,provider:this.id,model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-r}}}};function R(e=N()){switch(g(e.id).transport){case"gemini":return new _(e);case"cloudflare":return new v(e);default:return new O(e)}}var I=class{constructor(r){this.options=r}options;name="gemini";async embed(r){let t=this.options.model.replace(/^models\//,""),n=`${this.options.baseUrl?.replace(/\/+$/,"")||"https://generativelanguage.googleapis.com/v1beta"}/models/${encodeURIComponent(t)}:embedContent?key=${encodeURIComponent(this.options.apiKey)}`,s=await fetch(n,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:`models/${t}`,content:{parts:[{text:r}]}})});if(!s.ok)throw new Error(`Gemini embedding failed: ${s.status} ${await s.text()}`);let d=(await s.json()).embedding?.values;if(!Array.isArray(d)||d.length===0)throw new Error("Gemini embedding returned invalid response");return d}async embedMany(r){let t=[];for(let i of r)t.push(await this.embed(i));return t}};import{createHash as j}from"node:crypto";var L=class{name="hash-fallback";dimensions=128;async embed(r){let t=new Array(this.dimensions).fill(0),i=r.toLowerCase().split(/\s+/).filter(Boolean);for(let n of i){let l=j("sha256").update(n).digest().readUInt32BE(0)%this.dimensions;t[l]+=1}return q(t)}async embedMany(r){return Promise.all(r.map(t=>this.embed(t)))}};function q(e){let r=Math.sqrt(e.reduce((t,i)=>t+i*i,0));return r===0?e:e.map(t=>t/r)}var P=class{constructor(r){this.options=r;this.dimensions=r.dimensions}options;name="openai-compatible";dimensions;async embed(r){let[t]=await this.embedMany([r]);return t}async embedMany(r){if(r.length===0)return[];let t=this.options.baseUrl.replace(/\/+$/,""),i=await fetch(`${t}/embeddings`,{method:"POST",headers:{"content-type":"application/json",...this.options.apiKey?{authorization:`Bearer ${this.options.apiKey}`}:{}},body:JSON.stringify({model:this.options.model,input:r})});if(!i.ok)throw new Error(`Embedding failed: ${i.status} ${await i.text()}`);let s=(await i.json()).data?.sort((l,d)=>(l.index??0)-(d.index??0)).map(l=>l.embedding);if(!s||s.length!==r.length||s.some(l=>!Array.isArray(l)))throw new Error("Embedding provider returned invalid response");return s}};var M=class{constructor(r){this.options=r}options;name="huggingface";dimensions=384;async embed(r){let[t]=await this.embedMany([r]);return t}async embedMany(r){if(r.length===0)return[];let t=`https://router.huggingface.co/hf-inference/models/${this.options.model}/pipeline/feature-extraction`,i=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.options.token}`,"Content-Type":"application/json"},body:JSON.stringify({inputs:r,options:{wait_for_model:!0}})});if(!i.ok)throw new Error(`HF embedding failed: ${i.status} ${await i.text()}`);let n=await i.json();if(!Array.isArray(n))throw new Error("HF embedding returned invalid response");return n.map(s=>V(s))}};function V(e){if(!Array.isArray(e))throw new Error("Invalid embedding");if(e.length>0&&typeof e[0]=="number")return e;if(e.length>0&&Array.isArray(e[0])){let r=e;if(r.length===0)return[];let t=r[0].length,i=new Array(t).fill(0);for(let n of r)for(let s=0;s<t;s++)i[s]+=n[s]??0;for(let n=0;n<t;n++)i[n]/=r.length;return i}throw new Error("Unsupported embedding shape")}var w=class{constructor(r,t=new L){this.primary=r;this.fallback=t}primary;fallback;name="resilient";async embed(r){if(this.primary)try{return await this.primary.embed(r)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embed(r)}async embedMany(r){if(this.primary)try{return await this.primary.embedMany(r)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embedMany(r)}};function J(e){return`https://api.cloudflare.com/client/v4/accounts/${e}/ai/v1`}function z(){let e=u().embedding;if(e.provider==="local")return null;if(e.provider==="huggingface")return!e.apiKey||!e.model?null:new M({token:e.apiKey,model:e.model});if(e.provider==="gemini")return!e.apiKey||!e.model?null:new I({apiKey:e.apiKey,model:e.model,baseUrl:e.baseUrl});let r=e.baseUrl;return e.provider==="cloudflare"&&!r&&e.accountId&&(r=J(e.accountId)),r&&e.model?new P({apiKey:e.apiKey,baseUrl:r,model:e.model}):null}function K(){return new w(z())}var $=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],c={clear:"\r\x1B[2K",cyan:"\x1B[36m",green:"\x1B[32m",red:"\x1B[31m",yellow:"\x1B[33m",amber:"\x1B[38;5;214m",dim:"\x1B[2m",reset:"\x1B[0m"};function B(e,r=16){let i=Math.max(1,r-4+1),n=e%i;return"\u2500".repeat(n)+"\u2501".repeat(4)+"\u2500".repeat(Math.max(0,r-n-4))}function k(e){let r=Date.now()-e;return r<1e3?`${r}ms`:r<1e4?`${(r/1e3).toFixed(1)}s`:`${Math.round(r/1e3)}s`}var b=class{stream;enabled;interactive;color;intervalMs;display;label;frame=0;startedAt=0;timer;active=!1;constructor(r,t={}){this.label=r,this.stream=t.stream??process.stderr,this.enabled=t.enabled??!0,this.interactive=t.interactive??this.stream.isTTY===!0,this.color=t.color??(this.interactive&&process.env.NO_COLOR===void 0),this.intervalMs=Math.max(40,t.intervalMs??80),this.display=t.display??"spinner"}start(){return!this.enabled||this.active?this:(this.active=!0,this.startedAt=Date.now(),this.interactive?(this.render(),this.timer=setInterval(()=>{this.frame=(this.frame+1)%1e4,this.render()},this.intervalMs),this.timer.unref?.(),this):(this.stream.write(`\u2192 ${this.label}
4
- `),this))}update(r){return this.label=r,this.enabled&&this.active&&this.interactive&&this.render(),this}succeed(r){this.finish("\u2713",r??this.label,c.green)}fail(r){this.finish("\u2717",r??this.label,c.red)}warn(r){this.finish("!",r??this.label,c.yellow)}stop(){this.active&&(this.timer&&(clearInterval(this.timer),this.timer=void 0),this.enabled&&this.interactive&&this.stream.write(c.clear),this.active=!1)}render(){if(!this.enabled||!this.active||!this.interactive)return;let r=$[this.frame%$.length],t=this.display==="bar"?this.color?`${c.amber}${B(this.frame)}${c.reset}`:B(this.frame):this.color?`${c.cyan}${r}${c.reset}`:r,i=k(this.startedAt),n=this.color?`${c.dim}${i}${c.reset}`:i;this.stream.write(`${c.clear}${t} ${this.label} ${n}`)}finish(r,t,i){if(!this.enabled){this.active=!1;return}this.startedAt||(this.startedAt=Date.now()),this.timer&&(clearInterval(this.timer),this.timer=void 0);let n=k(this.startedAt),s=this.color?`${i}${r}${c.reset}`:r,l=this.color?`${c.dim}${n}${c.reset}`:n;this.interactive?this.stream.write(`${c.clear}${s} ${t} ${l}
5
- `):this.stream.write(`${s} ${t} (${n})
6
- `),this.active=!1}};function x(e){return e?e.length<=8?"********":`${e.slice(0,4)}...${e.slice(-4)}`:"not configured"}function W(){console.log(""),console.log("ToolNet AI Providers"),console.log("===================="),console.log("");for(let e of h)console.log(`- ${e.label}`),console.log(` id : ${e.id}`),console.log(` protocol : ${e.transport}`),e.defaultBaseUrl&&console.log(` base URL : ${e.defaultBaseUrl}`),e.defaultModel&&console.log(` model : ${e.defaultModel}`),console.log("");console.log("- Local / Hash embedding"),console.log(" id : local"),console.log(" protocol : local"),console.log("")}function Q(){let e=u();console.log(""),console.log("\u25C7 ToolNet AI Providers"),console.log(""),console.log("\u25C6 Configuration"),console.log("\u2502"),console.log(`\u251C \u25C6 LLM \u2014 ${e.llm.provider}`),console.log(`\u2502 Model \u2014 ${e.llm.model??"not configured"}`),console.log(`\u2502 Base URL \u2014 ${e.llm.baseUrl??"default/provider native"}`),console.log(`\u2502 API Key \u2014 ${x(e.llm.apiKey)}`),e.llm.accountId&&console.log(`\u2502 Account \u2014 ${e.llm.accountId}`),console.log(`\u2502 Legacy \u2014 ${e.legacy.llm?"yes":"no"}`),console.log("\u2502"),console.log(`\u251C \u25C6 Embedding \u2014 ${e.embedding.provider}`),console.log(`\u2502 Model \u2014 ${e.embedding.model??(e.embedding.provider==="local"?"local hash":"not configured")}`),console.log(`\u2502 Base URL \u2014 ${e.embedding.baseUrl??(e.embedding.provider==="local"?"local":"default/provider native")}`),console.log(`\u2502 API Key \u2014 ${e.embedding.provider==="local"?"not required":x(e.embedding.apiKey)}`),e.embedding.accountId&&console.log(`\u2502 Account \u2014 ${e.embedding.accountId}`),console.log(`\u2502 Legacy \u2014 ${e.legacy.embedding?"yes":"no"}`),console.log("\u2502"),console.log("\u2514 \u25C6 Configuration loaded"),console.log("")}async function S(){let e=u().llm,r=new b(`Testing LLM \u2014 ${e.provider}`,{stream:process.stdout,display:"bar",intervalMs:180}).start();try{let i=await R({id:e.provider,apiKey:e.apiKey,baseUrl:e.baseUrl,model:e.model,accountId:e.accountId}).healthCheck();if(!i.ok)return r.fail(`LLM \u2014 ${i.message}`),!1;let n=[e.provider,i.model??e.model,i.latencyMs!==void 0?`${i.latencyMs}ms`:void 0].filter(Boolean);return r.succeed(`LLM \u2014 ${n.join(" \xB7 ")}`),!0}catch(t){return r.fail(`LLM \u2014 ${t instanceof Error?t.message:String(t)}`),!1}}async function G(){let e=u().embedding,r=new b(`Testing embedding \u2014 ${e.provider}`,{stream:process.stdout,display:"bar",intervalMs:180}).start();try{let t=K(),i=Date.now(),n=await t.embed("ToolNet Memory provider health check"),s=Date.now()-i;if(!Array.isArray(n)||n.length===0)throw new Error("Empty embedding vector");return r.succeed(`Embedding \u2014 ${e.provider} \xB7 ${n.length}d \xB7 ${s}ms`),!0}catch(t){return r.fail(`Embedding \u2014 ${t instanceof Error?t.message:String(t)}`),!1}}async function X(){console.log(""),console.log("\u25C7 ToolNet AI Providers"),console.log(""),console.log("\u25C6 Health check"),console.log("\u2502");let e=await S(),r=await G();return console.log("\u2502"),console.log(e&&r?"\u2514 \u25C6 Providers ready":"\u2514 \u2717 Provider check failed"),console.log(""),e&&r}async function Z(){let e=process.argv[2]??"status";if(e==="list"){W();return}if(e==="status"){Q();return}if(e==="test"){let r=process.argv[3]??"all",t=!1;r==="llm"?t=await S():r==="embedding"?t=await G():t=await X(),process.exitCode=t?0:1;return}console.error(`Unknown provider command: ${e}`),console.error(""),console.error("Usage:"),console.error(" toolnet-memory provider:list"),console.error(" toolnet-memory provider:status"),console.error(" toolnet-memory provider:test"),console.error(" toolnet-memory provider:test llm"),console.error(" toolnet-memory provider:test embedding"),process.exitCode=1}Z().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});