@cachly-dev/mcp-server 0.10.176 → 0.10.178
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/dist/src/bedeutung.js +2 -2
- package/dist/src/embeddings.js +4 -4
- package/dist/src/handlers/brain.js +66 -66
- package/dist/src/handlers/fedbrain.js +5 -5
- package/dist/src/handlers/share.js +8 -8
- package/dist/src/index.js +140 -140
- package/dist/src/instanz-warten.js +1 -0
- package/dist/src/leeres-brain.js +3 -0
- package/dist/src/search.js +1 -1
- package/dist/src/startwissen.js +11 -0
- package/dist/src/zeitmessung.js +2 -0
- package/dist/src/zugang.js +3 -3
- package/glama.json +1 -1
- package/hooks/cachly-ambient-einblendung.mjs +12 -12
- package/package.json +1 -1
- package/server.json +3 -3
package/dist/src/bedeutung.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const x="cachly:lesson:vec:",E="cachly:lesson:vecname:",
|
|
2
|
-
`).slice(0,2e3)}class
|
|
1
|
+
const x="cachly:lesson:vec:",E="cachly:lesson:vecname:",v="cachly:lesson:vec2:",w="cachly:vek:nachtrag";function b(o){return o.replace(/[:_-]+/g," ").replace(/\s+/g," ").trim()}const f=1,c=7;function d(o){let e=0;for(const t of o){const n=Math.abs(t);n>e&&(e=n)}const i=e>0?e/127:1;let r=c+o.length;for(;r%4!==1;)r++;const s=Buffer.alloc(r);s.writeUInt8(f,0),s.writeUInt16LE(o.length,1),s.writeFloatLE(i,3);for(let t=0;t<o.length;t++){const n=Math.round(o[t]/i);s.writeInt8(n>127?127:n<-127?-127:n,c+t)}return s.toString("base64")}function k(o){try{const e=Buffer.from(o,"base64");if(e.byteLength===0)return null;if(e[0]===f&&e.byteLength%4===1&&e.byteLength>c){const r=e.readUInt16LE(1);if(r===0||c+r>e.byteLength)return null;const s=e.readFloatLE(3);if(!Number.isFinite(s))return null;const t=new Array(r);for(let n=0;n<r;n++)t[n]=e.readInt8(c+n)*s;return t}if(e.byteLength%4!==0)return null;const i=new Float32Array(e.buffer,e.byteOffset,e.byteLength/4);return Array.from(i)}catch{return null}}function u(o,e){if(o.length!==e.length)return-1;let i=0,r=0,s=0;for(let t=0;t<o.length;t++)i+=o[t]*e[t],r+=o[t]*o[t],s+=e[t]*e[t];return r&&s?i/Math.sqrt(r*s):0}function _(o){const e=i=>typeof i=="string"?i:"";return[e(o.topic),e(o.what_worked),e(o.what_failed)].filter(Boolean).join(`
|
|
2
|
+
`).slice(0,2e3)}class T{frischeMs;praefix;vektoren=new Map;geladen=0;constructor(e=6e4,i=x){this.frischeMs=e,this.praefix=i}naehe(e,i){const r=this.vektoren.get(`${this.praefix}${i}`);return r?u(e,r):-2}rohvektor(e){return this.vektoren.get(`${this.praefix}${e}`)??null}get groesse(){return this.vektoren.size}hat(e){return this.vektoren.has(`${this.praefix}${e}`)}themen(){return[...this.vektoren.keys()].map(e=>e.slice(this.praefix.length))}async aktualisiere(e,i=Date.now()){if(this.vektoren.size>0&&i-this.geladen<this.frischeMs)return;const r=[];let s="0";do{const[n,a]=await e.scan(s,"MATCH",`${this.praefix}*`,"COUNT",500);s=n,r.push(...a)}while(s!=="0");const t=r.filter(n=>!this.vektoren.has(n));for(let n=0;n<t.length;n+=100){const a=t.slice(n,n+100),g=await e.mget(...a);for(const[p,h]of g.entries()){if(!h)continue;const l=k(h);l&&this.vektoren.set(a[p],l)}}if(r.length<this.vektoren.size){const n=new Set(r);for(const a of[...this.vektoren.keys()])n.has(a)||this.vektoren.delete(a)}this.geladen=i}aehnlichste(e,i){const r=[];for(const[s,t]of this.vektoren)r.push({topic:s.slice(this.praefix.length),naehe:u(e,t)});return r.sort((s,t)=>t.naehe-s.naehe),r.slice(0,i)}}const y=.1;function m(o,e,i=y,r=60){const s=new Map;return o.forEach((t,n)=>s.set(t,(s.get(t)??0)+i/(r+n+1))),e.forEach((t,n)=>s.set(t,(s.get(t)??0)+(1-i)/(r+n+1))),[...s.entries()].sort((t,n)=>n[1]-t[1]).map(([t])=>t)}export{E as NAME_VEKTOR_PRAEFIX,w as VEKTOR_NACHTRAG,x as VEKTOR_PRAEFIX,T as Vektorbestand,y as WORT_GEWICHT,v as ZWEIT_VEKTOR_PRAEFIX,k as entpacke,u as kosinus,m as mischeRangfolgen,d as packe,b as textFuerNamensVektor,_ as textFuerVektor};
|
package/dist/src/embeddings.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
const s={apiUrl:process.env.CACHLY_API_URL??"https://api.cachly.dev",jwt:process.env.CACHLY_JWT??"",model:process.env.CACHLY_EMBED_MODEL??""};function
|
|
1
|
+
import{zeitpunkt as u}from"./zeitmessung.js";const s={apiUrl:process.env.CACHLY_API_URL??"https://api.cachly.dev",jwt:process.env.CACHLY_JWT??"",model:process.env.CACHLY_EMBED_MODEL??""};function v(n){s.jwt=n,n&&!b&&c==="none"&&(c="cachly")}const p=Number(process.env.CACHLY_EMBED_TIMEOUT_MS??8e3),A=Number(process.env.CACHLY_EMBED_TIMEOUT_MAX_MS??45e3),h=12;function f(n,r){return r==="kurz"?p:Math.min(A,p+n.length*h)}function g(){return process.env.CACHLY_JWT?"cachly":process.env.OLLAMA_BASE_URL?"ollama":"none"}const b=!!process.env.CACHLY_EMBED_PROVIDER;let c=(process.env.CACHLY_EMBED_PROVIDER??g()).toLowerCase();async function I(n,r,a){const d=f(n,r);switch(c){case"cachly":{if(!s.jwt)throw new Error(`CACHLY_JWT not set.
|
|
2
2
|
|
|
3
3
|
The "cachly" provider uses server-side embeddings via the Cachly API.
|
|
4
4
|
Set CACHLY_JWT, or use another provider via CACHLY_EMBED_PROVIDER:
|
|
5
5
|
openai \u2192 OPENAI_API_KEY
|
|
6
6
|
gemini \u2192 GEMINI_API_KEY
|
|
7
|
-
ollama \u2192 OLLAMA_BASE_URL (local, no key needed)`);const
|
|
7
|
+
ollama \u2192 OLLAMA_BASE_URL (local, no key needed)`);const e=`${s.apiUrl}/api/v1/embed`,o={text:n};(a??s.model)&&(o.model=a??s.model);const t=process.env.CACHLY_ADMIN_KEY??"",i=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.jwt}`,...t?{"X-Admin-Key":t}:{}},body:JSON.stringify(o),signal:AbortSignal.timeout(d)});if(!i.ok){const _=await i.text();let l=null;const m=Number(i.headers.get("retry-after"));if(Number.isFinite(m)&&m>=0)l=m;else try{const E=JSON.parse(_);typeof E.retry_after=="number"&&E.retry_after>=0&&(l=E.retry_after)}catch{}throw Object.assign(new Error(`Cachly embed API error ${i.status}: ${_.slice(0,200)}`),{status:i.status,retryAfterSek:l})}return(await i.json()).embedding}case"mistral":{const e=process.env.MISTRAL_API_KEY;if(!e)throw new Error("MISTRAL_API_KEY not set");const o=s.model!=="text-embedding-3-small"?s.model:"mistral-embed",t=await fetch("https://api.mistral.ai/v1/embeddings",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:o,input:[n]}),signal:AbortSignal.timeout(d)});if(!t.ok)throw new Error(`Mistral embedding error: ${t.statusText}`);const i=await t.json();if(!i.data?.[0]?.embedding)throw new Error("Mistral returned empty embedding response");return i.data[0].embedding}case"cohere":{const e=process.env.COHERE_API_KEY;if(!e)throw new Error("COHERE_API_KEY not set");const o=s.model!=="text-embedding-3-small"?s.model:"embed-english-v3.0",t=await fetch("https://api.cohere.com/v2/embed",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:o,texts:[n],input_type:"search_query",embedding_types:["float"]}),signal:AbortSignal.timeout(d)});if(!t.ok)throw new Error(`Cohere embedding error: ${t.statusText}`);return(await t.json()).embeddings.float[0]}case"ollama":{const e=process.env.OLLAMA_BASE_URL??"http://localhost:11434",o=a??(s.model!=="text-embedding-3-small"?s.model:"nomic-embed-text"),t=await fetch(`${e}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:o,prompt:n}),signal:AbortSignal.timeout(d)});if(!t.ok)throw new Error(`Ollama embedding error: ${t.statusText}`);return(await t.json()).embedding}case"gemini":{const e=process.env.GEMINI_API_KEY;if(!e)throw new Error("GEMINI_API_KEY not set");const o=s.model!=="text-embedding-3-small"?s.model:"text-embedding-004",t=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${o}:embedContent?key=${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:`models/${o}`,content:{parts:[{text:n}]}}),signal:AbortSignal.timeout(d)});if(!t.ok)throw new Error(`Gemini embedding error: ${t.statusText}`);return(await t.json()).embedding.values}case"openai":{const e=process.env.OPENAI_API_KEY;if(!e)throw new Error(`OPENAI_API_KEY not set.
|
|
8
8
|
|
|
9
9
|
Set OPENAI_API_KEY in your .env, or switch provider:
|
|
10
10
|
CACHLY_EMBED_PROVIDER=gemini (+ GEMINI_API_KEY)
|
|
11
11
|
CACHLY_EMBED_PROVIDER=ollama (local, free)
|
|
12
|
-
CACHLY_EMBED_PROVIDER=cachly (server-side, no key needed)`);const o=s.model||"text-embedding-3-small",
|
|
13
|
-
Supported: cachly (default), openai, mistral, cohere, ollama, gemini`)}}const
|
|
12
|
+
CACHLY_EMBED_PROVIDER=cachly (server-side, no key needed)`);const o=s.model||"text-embedding-3-small",t=await fetch("https://api.openai.com/v1/embeddings",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:o,input:n}),signal:AbortSignal.timeout(d)});if(!t.ok)throw new Error(`OpenAI embedding error: ${t.statusText}`);const i=await t.json();if(!i.data?.[0]?.embedding)throw new Error("OpenAI returned empty embedding response");return i.data[0].embedding}default:throw new Error(`Unknown CACHLY_EMBED_PROVIDER="${c}".
|
|
13
|
+
Supported: cachly (default), openai, mistral, cohere, ollama, gemini`)}}const y=3,w=4;function C(n){const r=n;if(typeof r?.status=="number")return r.status===429||r.status>=500;if(r?.name==="TimeoutError"||r?.name==="AbortError")return!1;if(/fetch failed/i.test(String(r?.message??"")))return!0;const a=r?.cause?.code??"";return["ECONNRESET","ECONNREFUSED","ETIMEDOUT","EAI_AGAIN","EPIPE","UND_ERR_SOCKET"].includes(a)}function P(n,r,a){if(r>=(a==="lang"?w:y)||!C(n))return null;const e=n?.retryAfterSek;if(typeof e=="number"&&Number.isFinite(e)&&e>=0){const o=e*1e3;return a==="kurz"?o<=2e3?o:null:Math.min(o,61e3)}return a==="lang"?Math.min(1e3*2**(r-1),8e3):250*2**(r-1)}async function S(n,r){const a=r?.geduld??"kurz";if(r?.modell&&c!=="cachly"&&c!=="ollama")throw new Error(`Anbieter "${c}" kann kein abweichendes Modell anfragen (verlangt: ${r.modell}).`);let d=0;for(;;){d++;try{u(`einbettung: Anfang (${n.length} Zeichen, Versuch ${d})`);const e=await I(n,a,r?.modell);return u("einbettung: fertig"),e}catch(e){const o=P(e,d,a);if(o===null)throw e;await new Promise(t=>setTimeout(t,o))}}}function T(){switch(c){case"cachly":return!!s.jwt;case"mistral":return!!process.env.MISTRAL_API_KEY;case"cohere":return!!process.env.COHERE_API_KEY;case"ollama":return!0;case"gemini":return!!process.env.GEMINI_API_KEY;case"openai":return!!process.env.OPENAI_API_KEY;case"none":return!1;default:return!1}}function Y(){const n={cachly:"CACHLY_JWT (server-side, no extra key needed)",openai:"OPENAI_API_KEY",mistral:"MISTRAL_API_KEY",cohere:"COHERE_API_KEY",ollama:"OLLAMA_BASE_URL (optional, default: http://localhost:11434)",gemini:"GEMINI_API_KEY"};if(c==="none")return"No embedding provider configured. Set OPENAI_API_KEY, GEMINI_API_KEY, or another provider key in .env. Brain works without embedding.";const r=n[c]??"CACHLY_JWT";return`CACHLY_EMBED_PROVIDER=${c} \u2192 requires ${r}`}export{c as EMBED_PROVIDER,S as computeEmbedding,s as embedConfig,Y as embedProviderHint,T as hasEmbedProvider,C as istVoruebergehend,v as setEmbedJwt,P as wiederholungMs,f as zeitlimitMs};
|