@cachly-dev/mcp-server 0.10.190 → 0.10.192
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/README.md +7 -3
- package/dist/src/ambient-cli.js +2 -2
- package/dist/src/ambient-hook.js +4 -2
- package/dist/src/einblendung.js +6 -6
- package/dist/src/hook-zugang.js +1 -1
- package/dist/src/index.js +131 -131
- package/dist/src/konto-anlegen.js +1 -0
- package/dist/src/lernen.js +6 -0
- package/dist/src/schreibbeleg.js +7 -5
- package/dist/src/sofort-test.js +1 -1
- package/glama.json +1 -1
- package/hooks/cachly-ambient-einblendung.mjs +30 -20
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{closeSync as w,existsSync as x,mkdirSync as y,openSync as _,readFileSync as M,renameSync as I,statSync as R,unlinkSync as z,writeFileSync as K,writeSync as F}from"node:fs";import{dirname as f,join as c}from"node:path";import{credentialsPath as j,readInstanceId as L,readSavedApiKey as b,saveApiKey as O,saveInstanceId as $}from"./credentials.js";import{holeSofortTest as D,SOFORT_TEST_FRIST_MS as U}from"./sofort-test.js";const A=15e3,H=100,Q=600*1e3,N=1440*60*1e3,T="anlegen.lock",G="anlegen.fehler",h="startwissen-auftrag.json";function Z(e=process.env){return!/^(0|false|off|no|nein)$/i.test((e.CACHLY_STARTWISSEN??"").trim())}function o(e){return f(j(e))}const P=e=>new Promise(n=>setTimeout(n,e));function k(e){return{apiKey:b(e),instanzId:L(e)}}function C(e,n){try{y(f(e),{recursive:!0})}catch{return"kein-zugriff"}try{const t=_(e,"wx",384);try{F(t,`${process.pid} ${n}`)}finally{w(t)}return"ja"}catch(t){return t?.code==="EEXIST"?"belegt":"kein-zugriff"}}function g(e,n){try{return n-R(e).mtimeMs}catch{return null}}function p(e){try{z(e)}catch{}}function J(e,n=Date.now()){const t=g(c(o(e),T),n);return t!==null&&t<A}function V(e,n,t){if(n<=0)return!1;const r=g(e,t);return r!==null&&r>=0&&r<n}function W(e){try{y(f(e),{recursive:!0}),K(e,String(Date.now()),{mode:384})}catch{}}async function ee(e){const n=e.jetzt??Date.now,t=e.schlafen??P,r=n()+e.fristMs,i=o(e),s=c(i,T),l=c(i,G);try{for(;;){const a=k(e);if(a.apiKey&&(a.instanzId||!J(e,n())))return{art:"vorhanden",apiKey:a.apiKey,instanzId:a.instanzId};if(!a.apiKey){const m=C(s,n());if(m==="kein-zugriff")return{art:"gescheitert",grund:"kein-schreibzugriff"};if(m==="ja")try{const d=k(e);if(d.apiKey)return{art:"vorhanden",apiKey:d.apiKey,instanzId:d.instanzId};if(V(l,e.abkuehlungMs??0,n()))return{art:"gescheitert",grund:"abgekuehlt"};const E=Math.max(500,r-n()),u=await D({apiUrl:e.apiUrl,version:e.version,holen:e.holen,env:e.env,fristMs:Math.min(E,e.anfrageMs??U),speichern:v=>O(v,e)});return u?($(u.instanzId,{...e,apiKey:u.apiKey}),p(l),{art:"angelegt",test:u}):(W(l),{art:"gescheitert",grund:"kein-test"})}finally{p(s)}const S=g(s,n());S!==null&&S>=A&&p(s)}if(n()>=r)return a.apiKey?{art:"vorhanden",apiKey:a.apiKey,instanzId:a.instanzId}:{art:"gescheitert",grund:"sperre-belegt"};await t(H)}}catch{return{art:"gescheitert",grund:"kein-test"}}}function ne(e,n={}){try{const t=c(o(n),h);y(f(t),{recursive:!0});const r=`${t}.${process.pid}.tmp`;K(r,JSON.stringify({...e,am:new Date().toISOString()}),{mode:384}),I(r,t)}catch{}}function te(e={}){return x(c(o(e),h))}function re(e={},n=Date.now()){const t=c(o(e),h),r=`${t}.${process.pid}.genommen`;try{I(t,r)}catch{return null}try{const i=JSON.parse(M(r,"utf8")),s=Date.parse(String(i?.am??""));return!i||typeof i.instanzId!="string"||!i.instanzId||!Number.isFinite(s)||n-s>N?null:{instanzId:i.instanzId,projekt:typeof i.projekt=="string"?i.projekt:"",am:String(i.am)}}catch{return null}finally{try{z(r)}catch{}}}export{Q as ABKUEHLUNG_HOOK_MS,N as AUFTRAG_VERFAELLT_MS,A as SPERRE_VERALTET_MS,H as WARTE_TAKT_MS,te as auftragLiegt,re as nimmAuftrag,ne as schreibeAuftrag,ee as sichereKonto,J as sperreLiegt,Z as startwissenEingeschaltet};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{appendFileSync as B,mkdirSync as U,readFileSync as S,readdirSync as K,rmSync as E,statSync as D,writeFileSync as y}from"node:fs";import{join as h}from"node:path";import{tmpdir as A}from"node:os";import{createHash as d,randomUUID as j}from"node:crypto";import{letzterZug as v}from"./schreibbeleg.js";const G=[{arm:0,name:"heute",minBelege:2,topK:3},{arm:1,name:"strenger",minBelege:3,topK:3},{arm:2,name:"knapper",minBelege:2,topK:1}],Ee=Math.min(...G.map(e=>e.minBelege)),k=[{a:20,b:80},{a:1.8,b:8.2},{a:1.8,b:8.2}],Z=1.645,w=30,F=.05,J=.5,P=.1,M=.1;function _(e,t,n){const o=String(e??"").trim();if(!o)return t;const a=o.endsWith("%"),r=Number(o.replace(/%$/,"").trim().replace(",","."));if(!Number.isFinite(r)||r<0)return t;const i=a||r>=1?r/100:r;return Math.min(i,n)}function b(e=process.env){return{aktiv:!["0","off","aus","false"].includes(String(e.CACHLY_LERNEN??"").trim().toLowerCase())&&e.CACHLY_NO_TELEMETRY!=="1",kontrolleAnteil:_(e.CACHLY_KONTROLLE_ANTEIL,F,J),erkundung:_(e.CACHLY_ERKUNDUNG,P,M)}}function q(e,t,n){const o=d("sha256").update(n).digest("hex"),a=d("sha256").update(`${e}|${t??""}|${o}`).digest();return{kontrolle:a.readUIntBE(0,6)/2**48,erkundung:a.readUIntBE(6,6)/2**48,saat:a.readUInt32BE(12)}}function V(e){let t=e>>>0;return()=>{t=t+1831565813>>>0;let n=t;return n=Math.imul(n^n>>>15,n|1),n^=n+Math.imul(n^n>>>7,n|61),((n^n>>>14)>>>0)/4294967296}}function W(e){const t=1-e();return Math.sqrt(-2*Math.log(t))*Math.cos(2*Math.PI*e())}function x(e,t){if(e<1)return x(e+1,t)*Math.pow(1-t(),1/e);const n=e-1/3,o=1/Math.sqrt(9*n);for(;;){let a,r;do a=W(t),r=1+o*a;while(r<=0);r=r*r*r;const i=1-t();if(i<1-.0331*a**4||Math.log(i)<.5*a*a+n*(1-r+Math.log(r)))return n*r}}function Y(e,t){const n=x(e.a,t),o=x(e.b,t);return n/(n+o)}function Q(e){return k.map((t,n)=>{const o=e?.find(i=>i?.arm===n),a=Math.max(0,Number(o?.erfolge)||0),r=Math.max(0,Number(o?.misserfolge)||0);return{a:t.a+a,b:t.b+r}})}function p(e){return e.a/(e.a+e.b)}function I(e){const t=e.a+e.b;return e.a*e.b/(t*t*(t+1))}function L(e,t){const n=k[t]??{a:0,b:0};return e[t].a+e[t].b-n.a-n.b}function X(e){if(L(e,0)<w)return 0;let t=0;for(let n=1;n<e.length;n++){if(L(e,n)<w)continue;(p(e[n])-p(e[0]))/Math.sqrt(I(e[n])+I(e[0]))>=Z&&p(e[n])>p(e[t])&&(t=n)}return t}function ee(e,t,n){const o=X(e);if(!(t.erkundung<Math.min(n,M)))return{arm:o,erkundet:!1};const a=V(t.saat);let r=o,i=-1;return e.forEach((u,s)=>{const l=Y(u,a);l>i&&(i=l,r=s)}),{arm:r,erkundet:r!==o}}function te(e,t){return t>0&&e<t}const ne={aktiv:!1,kontrolle:!1,arm:0,erkundet:!1};function be(e){const t=e.einstellungen??b();if(!t.aktiv)return ne;const n=q(e.instanceId,e.sitzung,e.prompt);if(te(n.kontrolle,t.kontrolleAnteil))return{aktiv:!0,kontrolle:!0,arm:0,erkundet:!1};const{arm:o,erkundet:a}=ee(Q(e.zaehlung),n,t.erkundung);return{aktiv:!0,kontrolle:!1,arm:o,erkundet:a}}function z(e){const t=e.trim();return t.length>=6&&/[:/_.-]/.test(t)}function re(e,t){const n=`${e.antwortText}
|
|
2
|
+
${e.werkzeugEingaben}`.toLowerCase();let o=0;t.forEach((r,i)=>{z(r.thema)&&n.includes(r.thema.trim().toLowerCase())&&(o|=1<<i)});const a=t.map((r,i)=>({k:r,i})).filter(({k:r})=>r.gezeigt&&z(r.thema));return a.length?{belohnung:a.some(({i:r})=>o&1<<r)?1:0,benutzt:o}:{belohnung:-1,benutzt:o}}const xe=5,oe=50,ae=1800*1e3,ie=10080*60*1e3,ue=10080*60*1e3,O=3e3;function c(e){return d("sha1").update(e).digest("hex").slice(0,12)}function se(e){return d("sha256").update(e.replace(/\s+/g," ").trim().slice(0,200)).digest("hex").slice(0,16)}function g(){return h(A(),"cachly-lernen")}function T(e,t){return h(g(),`${c(e)}-${c(t??"ohne")}.jsonl`)}function R(e){return h(A(),`cachly-lernen-arme-${c(e)}.json`)}function Ne(e){return c(e??"ohne")}function Se(e){return{id:j(),ts:new Date().toISOString(),belohnung:-1,benutzt:0,...e}}function ye(e,t,n){try{U(g(),{recursive:!0}),B(T(e,t),JSON.stringify(n)+`
|
|
3
|
+
`,{mode:384})}catch{}}function $(e){try{return S(e,"utf8").split(`
|
|
4
|
+
`).filter(t=>t.trim()).map(t=>{try{return JSON.parse(t)}catch{return null}}).filter(t=>!!t&&typeof t.id=="string"&&Array.isArray(t.kandidaten)).slice(-oe)}catch{return[]}}function le(e,t){return{id:t.id,ts:t.ts,sitzung:t.sitzung,ereignis:t.ereignis,editor:t.editor,arm:t.arm,kontrolle:t.kontrolle,erkundet:t.erkundet,ausgewaehlt:t.ausgewaehlt,kandidaten_zahl:t.kandidatenZahl,belege:t.belege,top_score:t.topScore,leser:t.leser,leser_ms:t.leserMs,quelle:t.quelle,bestand:t.bestand,belohnung:t.belohnung,benutzt:t.benutzt,merkmale:t.kandidaten.map(n=>({t:c(`${e}|${n.thema}`),r:n.rang,p:n.punkte,b:n.belege,l:n.leser,g:n.gezeigt}))}}async function C(e,t,n,o){if(!t.length)return!0;try{return(await n(`${e.apiUrl}/api/v1/instances/${e.instanceId}/einblendungen`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e.jwt}`},body:JSON.stringify({entscheidungen:t.map(r=>le(e.instanceId,r))}),signal:AbortSignal.timeout(o)})).ok}catch{return!1}}async function Ae(e,t,n,{fetchFn:o=fetch,zeitlimitMs:a=O,einstellungen:r}={}){try{if(!(r??b()).aktiv||!e?.jwt||!e?.instanceId)return null;const u=T(e.instanceId,t),s=$(u);if(!s.length)return null;let l=null;if(n){const f=v(n),H=se(f.frage),m=[...s].reverse().find(N=>N.belohnung===-1&&N.zug===H);m&&(l=re(f,m.kandidaten),m.belohnung=l.belohnung,m.benutzt=l.benutzt)}return await C(e,s,o,a)?E(u,{force:!0}):y(u,s.map(f=>JSON.stringify(f)).join(`
|
|
5
|
+
`)+`
|
|
6
|
+
`,{mode:384}),l}catch{return null}}async function ce(e,t,n,o){let a;try{a=K(g())}catch{return}const r=`${c(e.instanceId)}-`,i=[];for(const u of a){const s=h(g(),u);try{const l=o-D(s).mtimeMs;l>ie?E(s,{force:!0}):u.startsWith(r)&&l>=ae&&i.length<20&&i.push(s)}catch{}}await Promise.all(i.map(async u=>{await C(e,$(u),t,n)&&E(u,{force:!0})}))}async function fe(e,t,n){try{const o=await t(`${e.apiUrl}/api/v1/einblendung/arme`,{headers:{Authorization:`Bearer ${e.jwt}`},signal:AbortSignal.timeout(n)});if(!o.ok)return;const a=await o.json();if(!Array.isArray(a?.arme))return;const r=a.arme.filter(i=>i&&Number.isInteger(i.arm)).map(i=>({arm:i.arm,erfolge:Number(i.erfolge)||0,misserfolge:Number(i.misserfolge)||0}));y(R(e.instanceId),JSON.stringify({at:Date.now(),arme:r}),{mode:384})}catch{}}function ke(e,t=Date.now()){try{const n=JSON.parse(S(R(e),"utf8"));return!Array.isArray(n?.arme)||t-Number(n.at)>ue?null:n.arme}catch{return null}}async function we(e,{fetchFn:t=fetch,zeitlimitMs:n=O,einstellungen:o,jetzt:a=Date.now()}={}){try{if(!(o??b()).aktiv||!e?.jwt||!e?.instanceId)return;await Promise.all([fe(e,t,n),ce(e,t,n,a)])}catch{}}export{G as ARME,ue as ARME_VERFALL_MS,Ee as BASIS_MIN_BELEGE,M as ERKUNDUNG_HOECHSTENS,P as ERKUNDUNG_VORGABE,J as KONTROLLE_ANTEIL_HOECHSTENS,F as KONTROLLE_ANTEIL_VORGABE,O as MELDE_ZEITLIMIT_MS,xe as MERKMAL_KANDIDATEN,w as MINDEST_BEWERTUNGEN,ne as OHNE_LERNEN,ae as RUHE_MS,oe as SAETZE_HOECHSTENS,Z as SICHERHEIT_Z,ie as VERFALL_MS,k as VORWISSEN,R as armePfad,Ae as belohnungMelden,re as bewerteZug,be as entscheide,X as fuehrenderArm,le as fuerServer,te as istKontrolle,b as lernEinstellungen,g as lernOrdner,we as lernenAuffrischen,_ as leseAnteil,ke as leseArmZaehlung,ye as merkeEntscheidung,p as mittel,Se as neuerSatz,T as offenPfad,Q as posterior,Ne as sitzungsKennung,ee as waehleArm,z as zaehlbaresThema,Y as zieheBeta,q as zufallFuer,V as zufallsfolge,se as zugKennung};
|
package/dist/src/schreibbeleg.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import{createHash as
|
|
1
|
+
import{createHash as m}from"node:crypto";const y=/(?:^|__)(learn_from_attempts|remember_context|session_end|session_handoff|team_learn|global_learn|auto_learn_session)$/,_=/^\s*(✋|⛔|Error\b|Fehler\b|Update abgewiesen|Rejected)/i,g=/\bBeleg:\s*`?([0-9a-f]{8})`?/gi,x=[/\b(lektion(en)?|lesson|brain|gedaechtnis|gedächtnis|memory|cachly)\b[^.\n]{0,80}\b(gespeichert|abgelegt|eingetragen|festgehalten|hinterlegt|geschrieben|stored|saved|recorded|persisted)\b/i,/\b(gespeichert|abgelegt|eingetragen|festgehalten|hinterlegt|geschrieben|stored|saved|recorded|persisted|learned)\b[^.\n]{0,40}\b(im|ins|in the|to the|to|into)\s+(brain|gedaechtnis|gedächtnis|memory)\b/i,/\b(als|as an?)\s+(?!(?:die|der|das|den|dem|the)\b)(?:[\wäöüß-]+\s+){0,2}(lektion|lesson)\b/i];function z(n,e,t){return m("sha256").update(`${n}
|
|
2
2
|
${e}
|
|
3
|
-
${
|
|
4
|
-
`):""}function
|
|
5
|
-
`),
|
|
6
|
-
|
|
3
|
+
${t}`).digest("hex").slice(0,8)}const E=/\?\s*$|\b(soll ich|kann ich|darf ich|moechtest|möchtest|willst|wenn du|falls du|shall i|should i|would you|want me to|if you)\b/i,h="(?:die ki|das modell|der agent|der assistent|the (?:ai|model|agent|assistant)|claude)",d="(?:wenn|ob|falls|dass|behauptet|if|whether|claims?|says?)",w=new RegExp(`\\b${h}\\b[^.\\n]*?\\b${d}\\b|\\b${d}\\b[^.\\n]*?\\b${h}\\b`,"i"),S=/„[^“”"\n]*[“”"]|“[^”\n]*”|"[^"\n]*"|»[^«\n]*«|«[^»\n]*»|‚[^‘’\n]*[‘’]|(?<![\p{L}\p{N}])'[^'\n]*'(?![\p{L}\p{N}])/gu,A=/\b(sei|seien)\b|\b(sagt|sagte|meint|meinte|schreibt|schrieb|behauptet)\s+(er|sie|es|man)\b|\blaut\b|\baccording to\b|\b(he|she|they)\s+(says?|said|claims?|claimed|wrote)\b/i;function k(n){return n.replace(S," ")}function $(n){return n.split(/\n+/).filter(e=>!e.trim().startsWith("|")).map(k).flatMap(e=>e.split(/(?<=[.!?])\s+/)).some(e=>!E.test(e)&&!w.test(e)&&!A.test(e)&&x.some(t=>t.test(e)))}function u(n){const e=n.message?.content;return typeof e=="string"?[{type:"text",text:e}]:Array.isArray(e)?e:[]}function B(n){return typeof n.content=="string"?n.content:Array.isArray(n.content)?n.content.map(e=>typeof e?.text=="string"?e.text:"").join(`
|
|
4
|
+
`):""}function T(n){if(n.type!=="user"||n.isMeta||n.origin?.kind&&n.origin.kind!=="human")return!1;const e=u(n).filter(t=>t.type==="text").map(t=>t.text??"").join("");return e?!/^\s*<(task-notification|local-command|command-name|system-reminder)/.test(e):!1}function b(n){const e=[];for(const t of n)if(t.trim())try{const s=JSON.parse(t);s&&!s.isSidechain&&(s.type==="user"||s.type==="assistant")&&e.push(s)}catch{}for(let t=e.length-1;t>=0;t--)if(T(e[t]))return{frage:e[t],zug:e.slice(t+1)};return{frage:null,zug:e}}function I(n){const{frage:e,zug:t}=b(n);let s="",c="";for(const o of t)if(o.type==="assistant")for(const a of u(o))a.type==="text"&&a.text&&(s+=`${a.text}
|
|
5
|
+
`),a.type==="tool_use"&&(c+=`${a.name??""} ${JSON.stringify(a.input??{})}
|
|
6
|
+
`);return{frage:e?u(e).filter(o=>o.type==="text").map(o=>o.text??"").join(""):"",antwortText:s,werkzeugEingaben:c}}function N(n){const{zug:e}=b(n),t=new Set;let s="";for(const i of e)if(i.type==="assistant")for(const r of u(i))r.type==="text"&&r.text&&(s+=`${r.text}
|
|
7
|
+
`),r.type==="tool_use"&&r.id&&y.test(r.name??"")&&t.add(r.id);let c=0,l="";for(const i of e)if(i.type==="user")for(const r of u(i)){if(r.type!=="tool_result")continue;const f=B(r);l+=`${f}
|
|
8
|
+
`,r.tool_use_id&&t.has(r.tool_use_id)&&!r.is_error&&!_.test(f)&&c++}const o=new Set([...l.matchAll(g)].map(i=>i[1].toLowerCase())),a=[...s.matchAll(g)].map(i=>i[1].toLowerCase()),p=[...new Set(a.filter(i=>!o.has(i)))];return{behauptet:$(s),schreibaufrufe:t.size,erfolgreich:c,erfundeneBelege:p}}function Z(n,e){if(e)return"";const t=N(n),s=[];return t.erfundeneBelege.length&&s.push(`Die Antwort nennt Beleg ${t.erfundeneBelege.join(", ")}, den kein cachly-Werkzeug in diesem Zug ausgegeben hat.`),t.behauptet&&t.erfolgreich===0&&s.push(t.schreibaufrufe>0?"Die Antwort meldet eine Speicherung im Brain, aber der Schreibaufruf wurde abgewiesen oder schlug fehl.":"Die Antwort meldet eine Speicherung im Brain, aber in diesem Zug lief kein Schreibaufruf (learn_from_attempts, remember_context, session_end)."),s.length?JSON.stringify({decision:"block",reason:`cachly Schreibbeleg: ${s.join(" ")} Speichere jetzt wirklich oder korrigiere die Aussage gegenueber dem Nutzer. Bezieht sich die Aussage auf eine fruehere Speicherung, sag das ausdruecklich.`}):""}export{$ as behauptetSpeicherung,z as belegFuer,I as letzterZug,N as pruefeZug,Z as stopAntwort};
|
package/dist/src/sofort-test.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{saveApiKey as o}from"./credentials.js";function
|
|
1
|
+
import{saveApiKey as o}from"./credentials.js";function c(e,t=process.env){const n=t.CACHLY_QUELLE?.trim();return`${n&&/^[a-z0-9-]{1,40}$/.test(n)?`cachly-${n}`:"cachly-mcp"}/${e}`}function a(e){return`${e.replace(/\/+$/,"")}/auth/instant-trial`}function l(e){if(!e||typeof e!="object")return null;const t=e,n=typeof t.api_key=="string"?t.api_key:"",r=typeof t.instance_id=="string"?t.instance_id:"";return!n||!r?null:{apiKey:n,instanzId:r,tarifEndetAm:typeof t.trial_ends_at=="string"?t.trial_ends_at:void 0}}const u=8e3;let i=!1;function f(){i=!1}async function y(e){if(i)return null;i=!0;const t=e.holen??fetch,n=e.speichern??o;try{const r=await t(a(e.apiUrl),{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","User-Agent":c(e.version,e.env??process.env)},body:"{}",signal:AbortSignal.timeout(e.fristMs??u)});if(!r.ok)return null;const s=l(await r.json());return s?(n(s.apiKey),s):null}catch{return null}}export{u as SOFORT_TEST_FRIST_MS,f as _sperreZuruecksetzen,y as holeSofortTest,l as leseAntwort,a as sofortTestUrl,c as userAgent};
|