@nxuss/lemma 0.8.1 → 0.8.2
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/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +57 -119
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/observability/IdeContextSync.js +3 -3
- package/dist/cjs/observability/IdeContextSync.js.map +1 -1
- package/dist/cjs/proxy/ProjectStore.d.ts +2 -0
- package/dist/cjs/proxy/ProjectStore.d.ts.map +1 -1
- package/dist/cjs/proxy/ProjectStore.js +3 -1
- package/dist/cjs/proxy/ProjectStore.js.map +1 -1
- package/dist/cjs/proxy/SseRelay.d.ts +4 -25
- package/dist/cjs/proxy/SseRelay.d.ts.map +1 -1
- package/dist/cjs/proxy/SseRelay.js +60 -63
- package/dist/cjs/proxy/SseRelay.js.map +1 -1
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +29 -91
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/observability/IdeContextSync.js +1 -1
- package/dist/esm/observability/IdeContextSync.js.map +1 -1
- package/dist/esm/proxy/ProjectStore.d.ts +2 -0
- package/dist/esm/proxy/ProjectStore.d.ts.map +1 -1
- package/dist/esm/proxy/ProjectStore.js +2 -0
- package/dist/esm/proxy/ProjectStore.js.map +1 -1
- package/dist/esm/proxy/SseRelay.d.ts +4 -25
- package/dist/esm/proxy/SseRelay.d.ts.map +1 -1
- package/dist/esm/proxy/SseRelay.js +60 -60
- package/dist/esm/proxy/SseRelay.js.map +1 -1
- package/package.json +1 -1
- package/dist/cjs/protocol/iap.d.ts +0 -54
- package/dist/cjs/protocol/iap.d.ts.map +0 -1
- package/dist/cjs/protocol/iap.js +0 -108
- package/dist/cjs/protocol/iap.js.map +0 -1
- package/dist/cjs/subconscious/cache.d.ts +0 -34
- package/dist/cjs/subconscious/cache.d.ts.map +0 -1
- package/dist/cjs/subconscious/cache.js +0 -156
- package/dist/cjs/subconscious/cache.js.map +0 -1
- package/dist/cjs/subconscious/embeddings.d.ts +0 -25
- package/dist/cjs/subconscious/embeddings.d.ts.map +0 -1
- package/dist/cjs/subconscious/embeddings.js +0 -65
- package/dist/cjs/subconscious/embeddings.js.map +0 -1
- package/dist/esm/protocol/iap.d.ts +0 -54
- package/dist/esm/protocol/iap.d.ts.map +0 -1
- package/dist/esm/protocol/iap.js +0 -104
- package/dist/esm/protocol/iap.js.map +0 -1
- package/dist/esm/subconscious/cache.d.ts +0 -34
- package/dist/esm/subconscious/cache.d.ts.map +0 -1
- package/dist/esm/subconscious/cache.js +0 -152
- package/dist/esm/subconscious/cache.js.map +0 -1
- package/dist/esm/subconscious/embeddings.d.ts +0 -25
- package/dist/esm/subconscious/embeddings.d.ts.map +0 -1
- package/dist/esm/subconscious/embeddings.js +0 -58
- package/dist/esm/subconscious/embeddings.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lemma-proxy.d.ts","sourceRoot":"","sources":["../../../src/cli/lemma-proxy.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"lemma-proxy.d.ts","sourceRoot":"","sources":["../../../src/cli/lemma-proxy.ts"],"names":[],"mappings":";AAsbA,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA4DvF;AAmgED,wBAAsB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6KhL"}
|
|
@@ -45,25 +45,22 @@ const SemanticScrubber_1 = __importDefault(require("../security/SemanticScrubber
|
|
|
45
45
|
const CloudSyncClient_1 = __importDefault(require("../cloud/CloudSyncClient"));
|
|
46
46
|
const ContextSqueezer_1 = require("../utils/ContextSqueezer");
|
|
47
47
|
const AgentMultiplexer_1 = require("../proxy/AgentMultiplexer");
|
|
48
|
+
const SseRelay_1 = require("../proxy/SseRelay");
|
|
49
|
+
const KeyManager_1 = require("../proxy/KeyManager");
|
|
50
|
+
const Gatekeeper_1 = require("../proxy/Gatekeeper");
|
|
48
51
|
const ProjectRegistry_1 = require("../proxy/ProjectRegistry");
|
|
49
52
|
const ContextInjector_1 = require("../proxy/ContextInjector");
|
|
50
53
|
const SavingsLedger_1 = require("../utils/SavingsLedger");
|
|
54
|
+
const ProjectStore_1 = require("../proxy/ProjectStore");
|
|
51
55
|
const chroma = new chromadb_1.ChromaClient({ host: 'localhost', port: 8000 });
|
|
52
56
|
const dummyEmbeddingFunction = { generate: (texts) => Promise.resolve([]) };
|
|
53
57
|
const complexityRouter = new ComplexityRouter_1.default();
|
|
54
58
|
const semanticScrubber = new SemanticScrubber_1.default();
|
|
55
59
|
const cloudSync = new CloudSyncClient_1.default();
|
|
56
60
|
const agentMultiplexer = new AgentMultiplexer_1.AgentMultiplexer();
|
|
61
|
+
const keyManager = new KeyManager_1.KeyManager();
|
|
62
|
+
const gatekeeper = new Gatekeeper_1.Gatekeeper(keyManager);
|
|
57
63
|
// ── Paths ──────────────────────────────────────────────────────────────────────
|
|
58
|
-
const HOME = os_1.default.homedir();
|
|
59
|
-
const CACHE_DIR = path_1.default.join(HOME, '.lemma-cache');
|
|
60
|
-
const PID_FILE = path_1.default.join(CACHE_DIR, 'proxy.pid');
|
|
61
|
-
const PORT_FILE = path_1.default.join(CACHE_DIR, 'proxy.port');
|
|
62
|
-
const STATS_FILE = path_1.default.join(CACHE_DIR, 'stats.json');
|
|
63
|
-
const USAGE_FILE = path_1.default.join(CACHE_DIR, 'usage.json');
|
|
64
|
-
const LICENSE_FILE = path_1.default.join(CACHE_DIR, 'license.json');
|
|
65
|
-
const CLIPBOARD_PID_FILE = path_1.default.join(CACHE_DIR, 'clipboard.pid');
|
|
66
|
-
const FREE_LIMIT = 300;
|
|
67
64
|
const VALIDATE_URL = 'https://lemma.nxus.studio/api/validate-license';
|
|
68
65
|
async function checkDependency(url) {
|
|
69
66
|
try {
|
|
@@ -116,7 +113,7 @@ function detectProject() {
|
|
|
116
113
|
}
|
|
117
114
|
function ensureProjectDir(projectName) {
|
|
118
115
|
const hash = crypto_1.default.createHash('sha1').update(projectName).digest('hex').slice(0, 12);
|
|
119
|
-
const dir = path_1.default.join(CACHE_DIR, hash);
|
|
116
|
+
const dir = path_1.default.join(ProjectStore_1.CACHE_DIR, hash);
|
|
120
117
|
if (!fs_1.default.existsSync(dir)) {
|
|
121
118
|
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
122
119
|
}
|
|
@@ -143,7 +140,7 @@ async function ensureChromaRunning() {
|
|
|
143
140
|
catch {
|
|
144
141
|
console.log('⚠️ ChromaDB is not running. Starting it...');
|
|
145
142
|
const { spawn } = require('child_process');
|
|
146
|
-
const cp = spawn('chroma', ['run', '--path', path_1.default.join(CACHE_DIR, 'chroma_data')], {
|
|
143
|
+
const cp = spawn('chroma', ['run', '--path', path_1.default.join(ProjectStore_1.CACHE_DIR, 'chroma_data')], {
|
|
147
144
|
stdio: 'ignore',
|
|
148
145
|
detached: true,
|
|
149
146
|
});
|
|
@@ -471,8 +468,8 @@ function startBackgroundClipboardWatcher(cliOpts) {
|
|
|
471
468
|
return;
|
|
472
469
|
}
|
|
473
470
|
try {
|
|
474
|
-
if (fs_1.default.existsSync(CLIPBOARD_PID_FILE)) {
|
|
475
|
-
const oldPid = fs_1.default.readFileSync(CLIPBOARD_PID_FILE, 'utf8');
|
|
471
|
+
if (fs_1.default.existsSync(ProjectStore_1.CLIPBOARD_PID_FILE)) {
|
|
472
|
+
const oldPid = fs_1.default.readFileSync(ProjectStore_1.CLIPBOARD_PID_FILE, 'utf8');
|
|
476
473
|
try {
|
|
477
474
|
process.kill(parseInt(oldPid, 10), 0); // Check if process is still alive
|
|
478
475
|
console.log(`✅ [Clipboard] Watcher is already running in background (PID: ${oldPid})`);
|
|
@@ -481,7 +478,7 @@ function startBackgroundClipboardWatcher(cliOpts) {
|
|
|
481
478
|
catch {
|
|
482
479
|
// Process is dead, clean up pid file
|
|
483
480
|
try {
|
|
484
|
-
fs_1.default.unlinkSync(CLIPBOARD_PID_FILE);
|
|
481
|
+
fs_1.default.unlinkSync(ProjectStore_1.CLIPBOARD_PID_FILE);
|
|
485
482
|
}
|
|
486
483
|
catch { }
|
|
487
484
|
}
|
|
@@ -502,7 +499,7 @@ function startBackgroundClipboardWatcher(cliOpts) {
|
|
|
502
499
|
});
|
|
503
500
|
cp.unref();
|
|
504
501
|
if (cp.pid) {
|
|
505
|
-
fs_1.default.writeFileSync(CLIPBOARD_PID_FILE, String(cp.pid));
|
|
502
|
+
fs_1.default.writeFileSync(ProjectStore_1.CLIPBOARD_PID_FILE, String(cp.pid));
|
|
506
503
|
console.log(`✅ [Clipboard] Watcher has been started (PID: ${cp.pid})`);
|
|
507
504
|
}
|
|
508
505
|
}
|
|
@@ -511,21 +508,8 @@ function startBackgroundClipboardWatcher(cliOpts) {
|
|
|
511
508
|
}
|
|
512
509
|
}
|
|
513
510
|
// ── License helpers ────────────────────────────────────────────────────────────
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
const LICENSE_CACHE_TTL = 10000; // 10 seconds cache
|
|
517
|
-
async function loadLicense() {
|
|
518
|
-
return readJson(LICENSE_FILE, { isPro: false });
|
|
519
|
-
}
|
|
520
|
-
async function isPro() {
|
|
521
|
-
const now = Date.now();
|
|
522
|
-
if (isProCached !== null && (now - lastLicenseCheck) < LICENSE_CACHE_TTL) {
|
|
523
|
-
return isProCached;
|
|
524
|
-
}
|
|
525
|
-
const l = await loadLicense();
|
|
526
|
-
isProCached = !!(l && l.isPro);
|
|
527
|
-
lastLicenseCheck = now;
|
|
528
|
-
return isProCached;
|
|
511
|
+
function isPro() {
|
|
512
|
+
return gatekeeper.getMode() === 'pro';
|
|
529
513
|
}
|
|
530
514
|
async function validateKeyRemote(key) {
|
|
531
515
|
return new Promise((resolve, reject) => {
|
|
@@ -562,7 +546,7 @@ async function validateKeyRemote(key) {
|
|
|
562
546
|
}
|
|
563
547
|
// ── Usage helpers ──────────────────────────────────────────────────────────────
|
|
564
548
|
async function loadUsage() {
|
|
565
|
-
const u = await readJson(USAGE_FILE, { count: 0, lastReset: new Date().toISOString(), history: [] });
|
|
549
|
+
const u = await readJson(ProjectStore_1.USAGE_FILE, { count: 0, lastReset: new Date().toISOString(), history: [] });
|
|
566
550
|
const now = new Date();
|
|
567
551
|
const last = new Date(u.lastReset || 0);
|
|
568
552
|
if (now.getMonth() !== last.getMonth() || now.getFullYear() !== last.getFullYear()) {
|
|
@@ -571,14 +555,14 @@ async function loadUsage() {
|
|
|
571
555
|
lastReset: now.toISOString(),
|
|
572
556
|
history: [...(u.history || []), { month: last.toISOString().slice(0, 7), count: u.count }]
|
|
573
557
|
};
|
|
574
|
-
await writeJson(USAGE_FILE, fresh);
|
|
558
|
+
await writeJson(ProjectStore_1.USAGE_FILE, fresh);
|
|
575
559
|
return fresh;
|
|
576
560
|
}
|
|
577
561
|
return u;
|
|
578
562
|
}
|
|
579
563
|
// ── Stats helpers ──────────────────────────────────────────────────────────────
|
|
580
564
|
async function loadStats() {
|
|
581
|
-
return readJson(STATS_FILE, {});
|
|
565
|
+
return readJson(ProjectStore_1.STATS_FILE, {});
|
|
582
566
|
}
|
|
583
567
|
async function recordStat(stats, project, fromCache, latencyMs, provider, tokensSaved) {
|
|
584
568
|
if (!stats[project]) {
|
|
@@ -604,7 +588,7 @@ async function recordStat(stats, project, fromCache, latencyMs, provider, tokens
|
|
|
604
588
|
provider,
|
|
605
589
|
tokens: tkSaved
|
|
606
590
|
});
|
|
607
|
-
await writeJson(STATS_FILE, stats);
|
|
591
|
+
await writeJson(ProjectStore_1.STATS_FILE, stats);
|
|
608
592
|
}
|
|
609
593
|
const CACHE = new Map();
|
|
610
594
|
const TTL_MS = 86400000 * 7;
|
|
@@ -649,7 +633,7 @@ async function getEmbedding(text) {
|
|
|
649
633
|
}
|
|
650
634
|
}
|
|
651
635
|
async function semanticGet(provider, prompt, projectName = 'global') {
|
|
652
|
-
if (!
|
|
636
|
+
if (!isPro())
|
|
653
637
|
return null;
|
|
654
638
|
const emb = await getEmbedding(prompt);
|
|
655
639
|
if (!emb)
|
|
@@ -742,7 +726,7 @@ async function semanticGet(provider, prompt, projectName = 'global') {
|
|
|
742
726
|
return null;
|
|
743
727
|
}
|
|
744
728
|
async function semanticSet(provider, prompt, data, projectName = 'global') {
|
|
745
|
-
if (!
|
|
729
|
+
if (!isPro())
|
|
746
730
|
return;
|
|
747
731
|
const emb = await getEmbedding(prompt);
|
|
748
732
|
if (!emb)
|
|
@@ -845,53 +829,6 @@ function setSseHeaders(res, fromCache, similarity, tier) {
|
|
|
845
829
|
res.setHeader('X-Lemma-Similarity', (similarity || 1.0).toFixed(3));
|
|
846
830
|
res.setHeader('X-Lemma-Tier', tier);
|
|
847
831
|
}
|
|
848
|
-
function buildOaiChunk(id, model, text, stop) {
|
|
849
|
-
return { id, object: 'chat.completion.chunk', created: Math.floor(Date.now() / 1000), model,
|
|
850
|
-
choices: [{ index: 0, delta: stop ? {} : { content: text }, finish_reason: stop ? 'stop' : null }] };
|
|
851
|
-
}
|
|
852
|
-
function buildAntChunk(text, stop) {
|
|
853
|
-
if (stop)
|
|
854
|
-
return { type: 'message_stop' };
|
|
855
|
-
return { type: 'content_block_delta', index: 0, delta: { type: 'text_delta', text } };
|
|
856
|
-
}
|
|
857
|
-
function buildGemChunk(text, stop) {
|
|
858
|
-
return { candidates: [{ content: { parts: [{ text }] }, finishReason: stop ? 'STOP' : undefined }] };
|
|
859
|
-
}
|
|
860
|
-
async function simulateHitStream(res, cachedData, provider, model, tier, similarity, cacheHeader = 'HIT') {
|
|
861
|
-
setSseHeaders(res, cacheHeader, similarity, tier);
|
|
862
|
-
const id = `lemma-${Date.now()}`;
|
|
863
|
-
let text = '';
|
|
864
|
-
try {
|
|
865
|
-
if (provider === 'openai')
|
|
866
|
-
text = cachedData?.choices?.[0]?.message?.content || '';
|
|
867
|
-
else if (provider === 'anthropic') {
|
|
868
|
-
const c = cachedData?.content;
|
|
869
|
-
text = Array.isArray(c) ? c.map((x) => x.text || '').join('') : String(c || '');
|
|
870
|
-
}
|
|
871
|
-
else if (provider === 'gemini') {
|
|
872
|
-
text = cachedData?.candidates?.[0]?.content?.parts?.[0]?.text || '';
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
catch { }
|
|
876
|
-
const chunkSize = 30;
|
|
877
|
-
for (let i = 0; i < text.length; i += chunkSize) {
|
|
878
|
-
const chunk = text.slice(i, i + chunkSize);
|
|
879
|
-
let evt;
|
|
880
|
-
if (provider === 'openai')
|
|
881
|
-
evt = buildOaiChunk(id, model, chunk, false);
|
|
882
|
-
else if (provider === 'anthropic')
|
|
883
|
-
evt = buildAntChunk(chunk, false);
|
|
884
|
-
else if (provider === 'gemini')
|
|
885
|
-
evt = buildGemChunk(chunk, false);
|
|
886
|
-
res.write(provider === 'gemini' ? `${JSON.stringify(evt)}\n` : `data: ${JSON.stringify(evt)}\n\n`);
|
|
887
|
-
await new Promise(r => setTimeout(r, 15));
|
|
888
|
-
}
|
|
889
|
-
const stopEvt = provider === 'openai' ? buildOaiChunk(id, model, '', true) : (provider === 'anthropic' ? buildAntChunk('', true) : buildGemChunk('', true));
|
|
890
|
-
res.write(provider === 'gemini' ? `${JSON.stringify(stopEvt)}\n` : `data: ${JSON.stringify(stopEvt)}\n\n`);
|
|
891
|
-
if (provider !== 'gemini')
|
|
892
|
-
res.write('data: [DONE]\n\n');
|
|
893
|
-
res.end();
|
|
894
|
-
}
|
|
895
832
|
async function relayMissStream(res, body, provider, tier) {
|
|
896
833
|
setSseHeaders(res, false, 1.0, tier);
|
|
897
834
|
const apiKey = provider === 'openai' ? process.env.OPENAI_API_KEY : process.env.ANTHROPIC_API_KEY;
|
|
@@ -1001,8 +938,8 @@ class LemmaServer {
|
|
|
1001
938
|
}
|
|
1002
939
|
setupRoutes() {
|
|
1003
940
|
this.app.get('/health', async (req, res) => {
|
|
1004
|
-
const
|
|
1005
|
-
res.json({ status: 'ok', project: this.projectName, mode:
|
|
941
|
+
const gs = gatekeeper.getStatus();
|
|
942
|
+
res.json({ status: 'ok', project: this.projectName, mode: gs.mode, tier: gs.isPro ? 'pro' : 'free', port: this.port });
|
|
1006
943
|
});
|
|
1007
944
|
// MCP Status endpoint
|
|
1008
945
|
this.app.get('/api/mcp-status', (req, res) => {
|
|
@@ -1101,7 +1038,7 @@ class LemmaServer {
|
|
|
1101
1038
|
activeAgents,
|
|
1102
1039
|
totalAgents,
|
|
1103
1040
|
uptime: process.uptime(),
|
|
1104
|
-
tier: (
|
|
1041
|
+
tier: (isPro()) ? 'pro' : 'free'
|
|
1105
1042
|
});
|
|
1106
1043
|
});
|
|
1107
1044
|
this.app.get('/api/agents', async (req, res) => {
|
|
@@ -1312,7 +1249,7 @@ class LemmaServer {
|
|
|
1312
1249
|
totalTokensSaved: 0,
|
|
1313
1250
|
providers: {}
|
|
1314
1251
|
};
|
|
1315
|
-
writeJson(STATS_FILE, this.stats);
|
|
1252
|
+
writeJson(ProjectStore_1.STATS_FILE, this.stats);
|
|
1316
1253
|
}
|
|
1317
1254
|
// Clear Chroma DB collection
|
|
1318
1255
|
try {
|
|
@@ -1536,7 +1473,7 @@ class LemmaServer {
|
|
|
1536
1473
|
s.providers['mcp'] = { hits: 0, misses: 0 };
|
|
1537
1474
|
source === 'cache' ? s.providers['mcp'].hits++ : s.providers['mcp'].misses++;
|
|
1538
1475
|
// Write updated stats back to disk immediately
|
|
1539
|
-
writeJson(STATS_FILE, this.stats);
|
|
1476
|
+
writeJson(ProjectStore_1.STATS_FILE, this.stats);
|
|
1540
1477
|
// Push to live telemetry logEvent array so the Dashboard event timeline updates instantly!
|
|
1541
1478
|
logEvent({
|
|
1542
1479
|
type: source === 'cache' ? 'cache:hit' : source,
|
|
@@ -1688,14 +1625,14 @@ class LemmaServer {
|
|
|
1688
1625
|
}
|
|
1689
1626
|
async handleCompletion(req, res, provider) {
|
|
1690
1627
|
const t0 = Date.now();
|
|
1691
|
-
const pro =
|
|
1628
|
+
const pro = isPro();
|
|
1692
1629
|
const tier = pro ? 'pro' : 'standard';
|
|
1693
1630
|
const isStream = !!req.body.stream;
|
|
1694
1631
|
let historyTokensSaved = 0;
|
|
1695
1632
|
if (!pro) {
|
|
1696
1633
|
const usage = await loadUsage();
|
|
1697
|
-
if (usage.count >=
|
|
1698
|
-
return res.status(429).json({ error: { message: `Free tier limit (${
|
|
1634
|
+
if (usage.count >= ProjectStore_1.FREE_TIER_LIMIT) {
|
|
1635
|
+
return res.status(429).json({ error: { message: `Free tier limit (${ProjectStore_1.FREE_TIER_LIMIT}/mo). Upgrade: https://lemma.nxus.studio/upgrade` } });
|
|
1699
1636
|
}
|
|
1700
1637
|
}
|
|
1701
1638
|
const rawPrompt = extractPrompt(req.body, provider);
|
|
@@ -1714,7 +1651,7 @@ class LemmaServer {
|
|
|
1714
1651
|
await recordStat(this.stats, this.projectName, true, Date.now() - t0, provider, cacheTokensSaved);
|
|
1715
1652
|
const unmaskedData = semanticScrubber.unmask(hit.data, tokenMap);
|
|
1716
1653
|
if (isStream)
|
|
1717
|
-
return
|
|
1654
|
+
return SseRelay_1.SseRelay.simulateHit(res, unmaskedData, { provider: provider, tier, similarity: 1.0 });
|
|
1718
1655
|
res.setHeader('X-Lemma-Cache', 'HIT');
|
|
1719
1656
|
res.setHeader('X-Lemma-Similarity', '1.000');
|
|
1720
1657
|
res.setHeader('X-Lemma-Tier', tier);
|
|
@@ -1729,7 +1666,7 @@ class LemmaServer {
|
|
|
1729
1666
|
const unmaskedData = semanticScrubber.unmask(semHit.data, tokenMap);
|
|
1730
1667
|
const cacheHeader = semHit.hiveMind ? 'HIT-HIVE-MIND' : 'HIT';
|
|
1731
1668
|
if (isStream)
|
|
1732
|
-
return
|
|
1669
|
+
return SseRelay_1.SseRelay.simulateHit(res, unmaskedData, { provider: provider, tier, similarity: semHit.similarity, cacheHeader });
|
|
1733
1670
|
res.setHeader('X-Lemma-Cache', cacheHeader);
|
|
1734
1671
|
res.setHeader('X-Lemma-Similarity', semHit.similarity.toFixed(3));
|
|
1735
1672
|
res.setHeader('X-Lemma-Tier', tier);
|
|
@@ -1779,7 +1716,7 @@ Adjusted Answer:`;
|
|
|
1779
1716
|
await recordStat(this.stats, this.projectName, true, Date.now() - t0, provider, 2000);
|
|
1780
1717
|
const unmaskedData = semanticScrubber.unmask(synthesizedData, tokenMap);
|
|
1781
1718
|
if (isStream) {
|
|
1782
|
-
return
|
|
1719
|
+
return SseRelay_1.SseRelay.simulateHit(res, unmaskedData, { provider: provider, tier, similarity: semHit.similarity });
|
|
1783
1720
|
}
|
|
1784
1721
|
res.setHeader('X-Lemma-Cache', 'HIT-CARS');
|
|
1785
1722
|
res.setHeader('X-Lemma-Similarity', semHit.similarity.toFixed(3));
|
|
@@ -1799,7 +1736,7 @@ Adjusted Answer:`;
|
|
|
1799
1736
|
await recordStat(this.stats, this.projectName, true, Date.now() - t0, provider, 2000);
|
|
1800
1737
|
const unmaskedData = semanticScrubber.unmask(cloudHit.data, tokenMap);
|
|
1801
1738
|
if (isStream)
|
|
1802
|
-
return
|
|
1739
|
+
return SseRelay_1.SseRelay.simulateHit(res, unmaskedData, { provider: provider, tier, similarity: cloudHit.similarity || 0.95 });
|
|
1803
1740
|
res.setHeader('X-Lemma-Cache', 'HIT');
|
|
1804
1741
|
res.setHeader('X-Lemma-Similarity', (cloudHit.similarity || 0.95).toFixed(3));
|
|
1805
1742
|
res.setHeader('X-Lemma-Tier', tier);
|
|
@@ -1892,7 +1829,7 @@ Adjusted Answer:`;
|
|
|
1892
1829
|
await usageWriteQueue.enqueue(async () => {
|
|
1893
1830
|
const u = await loadUsage();
|
|
1894
1831
|
u.count++;
|
|
1895
|
-
await writeJson(USAGE_FILE, u);
|
|
1832
|
+
await writeJson(ProjectStore_1.USAGE_FILE, u);
|
|
1896
1833
|
});
|
|
1897
1834
|
}
|
|
1898
1835
|
return relayMissStream(res, req.body, provider, tier);
|
|
@@ -1908,7 +1845,7 @@ Adjusted Answer:`;
|
|
|
1908
1845
|
await usageWriteQueue.enqueue(async () => {
|
|
1909
1846
|
const u = await loadUsage();
|
|
1910
1847
|
u.count++;
|
|
1911
|
-
await writeJson(USAGE_FILE, u);
|
|
1848
|
+
await writeJson(ProjectStore_1.USAGE_FILE, u);
|
|
1912
1849
|
});
|
|
1913
1850
|
}
|
|
1914
1851
|
await recordStat(this.stats, this.projectName, false, Date.now() - t0, provider, historyTokensSaved);
|
|
@@ -2008,8 +1945,8 @@ Adjusted Answer:`;
|
|
|
2008
1945
|
});
|
|
2009
1946
|
const BIND_HOST = process.env.LEMMA_BIND_HOST || '127.0.0.1';
|
|
2010
1947
|
server.listen(this.port, BIND_HOST, async () => {
|
|
2011
|
-
fs_1.default.writeFileSync(PID_FILE, String(process.pid));
|
|
2012
|
-
fs_1.default.writeFileSync(PORT_FILE, String(this.port));
|
|
1948
|
+
fs_1.default.writeFileSync(ProjectStore_1.PID_FILE, String(process.pid));
|
|
1949
|
+
fs_1.default.writeFileSync(ProjectStore_1.PORT_FILE, String(this.port));
|
|
2013
1950
|
// Security warning if binding to all interfaces without auth
|
|
2014
1951
|
if (BIND_HOST !== '127.0.0.1' && BIND_HOST !== 'localhost') {
|
|
2015
1952
|
const authEnabled = process.env.AUTH_ENABLED === 'true';
|
|
@@ -2018,7 +1955,7 @@ Adjusted Answer:`;
|
|
|
2018
1955
|
console.warn(` Set AUTH_ENABLED=true and AUTH_REQUIRE_API_KEY=true before exposing to any network.\x1b[0m\n`);
|
|
2019
1956
|
}
|
|
2020
1957
|
}
|
|
2021
|
-
const pro =
|
|
1958
|
+
const pro = isPro();
|
|
2022
1959
|
console.log(`\x1b[1m\x1b[35m┌──────────────────────────────────────────────────────────┐\x1b[0m`);
|
|
2023
1960
|
console.log(`\x1b[1m\x1b[35m│ 🚀 LEMMA PROXY v${VERSION} — THE UNIVERSAL AI GATEWAY │\x1b[0m`);
|
|
2024
1961
|
console.log(`\x1b[1m\x1b[35m└──────────────────────────────────────────────────────────┘\x1b[0m`);
|
|
@@ -2112,7 +2049,7 @@ commander_1.program
|
|
|
2112
2049
|
.version(VERSION)
|
|
2113
2050
|
.addHelpText('after', `
|
|
2114
2051
|
\x1b[1mPlan Comparison\x1b[0m
|
|
2115
|
-
\x1b[32mFree\x1b[0m ${
|
|
2052
|
+
\x1b[32mFree\x1b[0m ${ProjectStore_1.FREE_TIER_LIMIT} req/mo · Exact cache · Privacy firewall · MCP tools
|
|
2116
2053
|
\x1b[35mPro\x1b[0m Unlimited · Semantic cache · Cloud sync · Autopilot · Heal
|
|
2117
2054
|
\x1b[36mhttps://lemma.nxus.studio/upgrade\x1b[0m
|
|
2118
2055
|
|
|
@@ -2188,7 +2125,7 @@ commander_1.program.command('start')
|
|
|
2188
2125
|
const runAutopilot = opts.autopilot || opts.stack;
|
|
2189
2126
|
if (runAutopilot) {
|
|
2190
2127
|
try {
|
|
2191
|
-
const pro =
|
|
2128
|
+
const pro = isPro();
|
|
2192
2129
|
if (!pro) {
|
|
2193
2130
|
if (opts.autopilot) {
|
|
2194
2131
|
console.log(`\n🛸 \x1b[35m[Autopilot]\x1b[0m Active background auto-healing watcher is a Lemma Pro feature.`);
|
|
@@ -2211,7 +2148,7 @@ commander_1.program.command('start')
|
|
|
2211
2148
|
if (opts.stack) {
|
|
2212
2149
|
const { spawn } = require('child_process');
|
|
2213
2150
|
console.log('🚀 Launching Lemma Full Stack...');
|
|
2214
|
-
const chromaDataPath = path_1.default.join(CACHE_DIR, 'chroma_data');
|
|
2151
|
+
const chromaDataPath = path_1.default.join(ProjectStore_1.CACHE_DIR, 'chroma_data');
|
|
2215
2152
|
if (!fs_1.default.existsSync(chromaDataPath)) {
|
|
2216
2153
|
fs_1.default.mkdirSync(chromaDataPath, { recursive: true });
|
|
2217
2154
|
}
|
|
@@ -2258,8 +2195,8 @@ commander_1.program.command('stop')
|
|
|
2258
2195
|
const port = parseInt(opts.port, 10);
|
|
2259
2196
|
let stopped = false;
|
|
2260
2197
|
try {
|
|
2261
|
-
if (fs_1.default.existsSync(PID_FILE)) {
|
|
2262
|
-
const pid = fs_1.default.readFileSync(PID_FILE, 'utf8');
|
|
2198
|
+
if (fs_1.default.existsSync(ProjectStore_1.PID_FILE)) {
|
|
2199
|
+
const pid = fs_1.default.readFileSync(ProjectStore_1.PID_FILE, 'utf8');
|
|
2263
2200
|
try {
|
|
2264
2201
|
process.kill(parseInt(pid), 'SIGTERM');
|
|
2265
2202
|
stopped = true;
|
|
@@ -2284,18 +2221,18 @@ commander_1.program.command('stop')
|
|
|
2284
2221
|
catch {
|
|
2285
2222
|
console.log('⚠️ Could not stop process.');
|
|
2286
2223
|
}
|
|
2287
|
-
if (fs_1.default.existsSync(PID_FILE))
|
|
2288
|
-
fs_1.default.unlinkSync(PID_FILE);
|
|
2224
|
+
if (fs_1.default.existsSync(ProjectStore_1.PID_FILE))
|
|
2225
|
+
fs_1.default.unlinkSync(ProjectStore_1.PID_FILE);
|
|
2289
2226
|
// Stop background Clipboard Watcher if active
|
|
2290
2227
|
try {
|
|
2291
|
-
if (fs_1.default.existsSync(CLIPBOARD_PID_FILE)) {
|
|
2292
|
-
const cbPid = fs_1.default.readFileSync(CLIPBOARD_PID_FILE, 'utf8');
|
|
2228
|
+
if (fs_1.default.existsSync(ProjectStore_1.CLIPBOARD_PID_FILE)) {
|
|
2229
|
+
const cbPid = fs_1.default.readFileSync(ProjectStore_1.CLIPBOARD_PID_FILE, 'utf8');
|
|
2293
2230
|
try {
|
|
2294
2231
|
process.kill(parseInt(cbPid, 10), 'SIGTERM');
|
|
2295
2232
|
console.log(`✅ Stopped background Clipboard Watcher (PID: ${cbPid})`);
|
|
2296
2233
|
}
|
|
2297
2234
|
catch { }
|
|
2298
|
-
fs_1.default.unlinkSync(CLIPBOARD_PID_FILE);
|
|
2235
|
+
fs_1.default.unlinkSync(ProjectStore_1.CLIPBOARD_PID_FILE);
|
|
2299
2236
|
}
|
|
2300
2237
|
}
|
|
2301
2238
|
catch { }
|
|
@@ -2303,7 +2240,7 @@ commander_1.program.command('stop')
|
|
|
2303
2240
|
commander_1.program.command('status')
|
|
2304
2241
|
.description('Check proxy status')
|
|
2305
2242
|
.action(async () => {
|
|
2306
|
-
const port = fs_1.default.existsSync(PORT_FILE) ? fs_1.default.readFileSync(PORT_FILE, 'utf8') : '8081';
|
|
2243
|
+
const port = fs_1.default.existsSync(ProjectStore_1.PORT_FILE) ? fs_1.default.readFileSync(ProjectStore_1.PORT_FILE, 'utf8') : '8081';
|
|
2307
2244
|
try {
|
|
2308
2245
|
const resp = await axios_1.default.get(`http://localhost:${port}/health`, { timeout: 1000 });
|
|
2309
2246
|
if (resp.data && resp.data.status === 'ok') {
|
|
@@ -2315,8 +2252,8 @@ commander_1.program.command('status')
|
|
|
2315
2252
|
}
|
|
2316
2253
|
catch {
|
|
2317
2254
|
console.log('❌ Stopped');
|
|
2318
|
-
if (fs_1.default.existsSync(PID_FILE))
|
|
2319
|
-
fs_1.default.unlinkSync(PID_FILE);
|
|
2255
|
+
if (fs_1.default.existsSync(ProjectStore_1.PID_FILE))
|
|
2256
|
+
fs_1.default.unlinkSync(ProjectStore_1.PID_FILE);
|
|
2320
2257
|
}
|
|
2321
2258
|
});
|
|
2322
2259
|
commander_1.program.command('stats')
|
|
@@ -2332,9 +2269,9 @@ commander_1.program.command('stats')
|
|
|
2332
2269
|
console.log(`Cache Hits : ${s.hits} (${((s.hits / s.total || 0) * 100).toFixed(1)}%)`);
|
|
2333
2270
|
console.log(`Tokens Saved : ${s.totalTokensSaved.toLocaleString()}`);
|
|
2334
2271
|
console.log(`Avg Latency : ${(s.totalLatency / (s.total || 1)).toFixed(2)}ms`);
|
|
2335
|
-
console.log(`Tier : ${(
|
|
2336
|
-
if (!
|
|
2337
|
-
console.log(`Free Usage : ${usage.count}/${
|
|
2272
|
+
console.log(`Tier : ${(isPro()) ? 'PRO' : 'FREE'}`);
|
|
2273
|
+
if (!isPro())
|
|
2274
|
+
console.log(`Free Usage : ${usage.count}/${ProjectStore_1.FREE_TIER_LIMIT} requests`);
|
|
2338
2275
|
console.log(`──────────────────────────────────\n`);
|
|
2339
2276
|
});
|
|
2340
2277
|
commander_1.program.command('activate <key>')
|
|
@@ -2349,7 +2286,8 @@ commander_1.program.command('activate <key>')
|
|
|
2349
2286
|
try {
|
|
2350
2287
|
const res = await validateKeyRemote(key.trim());
|
|
2351
2288
|
if (res.valid) {
|
|
2352
|
-
await writeJson(LICENSE_FILE, { key, isPro: true, activatedAt: new Date().toISOString(), validatedRemotely: true });
|
|
2289
|
+
await writeJson(ProjectStore_1.LICENSE_FILE, { key, isPro: true, activatedAt: new Date().toISOString(), validatedRemotely: true });
|
|
2290
|
+
gatekeeper.reload();
|
|
2353
2291
|
console.log('✅ License activated! Enjoy Pro features (Server-verified).');
|
|
2354
2292
|
}
|
|
2355
2293
|
else {
|
|
@@ -2590,7 +2528,7 @@ commander_1.program.command('heal')
|
|
|
2590
2528
|
.option('--apply', 'Apply the auto-generated code fix automatically', false)
|
|
2591
2529
|
.action(async (opts) => {
|
|
2592
2530
|
try {
|
|
2593
|
-
const pro =
|
|
2531
|
+
const pro = isPro();
|
|
2594
2532
|
if (!pro) {
|
|
2595
2533
|
console.log(`\n🩺 \x1b[35m[Heal]\x1b[0m Guided code diagnostics and auto-healing is a Lemma Pro feature.`);
|
|
2596
2534
|
console.log(`💡 Upgrade to Pro in your Dashboard or visit: \x1b[4mhttps://lemma.nxus.studio/upgrade\x1b[0m\n`);
|
|
@@ -2619,7 +2557,7 @@ commander_1.program.command('autopilot')
|
|
|
2619
2557
|
.option('--dir <directory>', 'Directory to monitor for changes', 'src')
|
|
2620
2558
|
.action(async (opts) => {
|
|
2621
2559
|
try {
|
|
2622
|
-
const pro =
|
|
2560
|
+
const pro = isPro();
|
|
2623
2561
|
if (!pro) {
|
|
2624
2562
|
console.log(`\n🛸 \x1b[35m[Autopilot]\x1b[0m Active background auto-healing watcher is a Lemma Pro feature.`);
|
|
2625
2563
|
console.log(`💡 Upgrade to Pro in your Dashboard or visit: \x1b[4mhttps://lemma.nxus.studio/upgrade\x1b[0m\n`);
|