@ik-firewall/core 2.2.0 → 2.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/dist/index.cjs +327 -104
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +317 -104
- package/package.json +2 -2
- package/scripts/setup-runtime.js +3 -1
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -48,15 +58,18 @@ if (typeof window === "undefined") {
|
|
|
48
58
|
var Registry = class _Registry {
|
|
49
59
|
static instance;
|
|
50
60
|
registryPath;
|
|
61
|
+
usagePath;
|
|
51
62
|
hasWarnedNoFs = false;
|
|
52
63
|
hasWarnedSaveError = false;
|
|
53
64
|
constructor() {
|
|
54
65
|
this.registryPath = "";
|
|
66
|
+
this.usagePath = "";
|
|
55
67
|
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
56
68
|
try {
|
|
57
69
|
fs = require("fs");
|
|
58
70
|
path = require("path");
|
|
59
71
|
this.registryPath = path.join(process.cwd(), ".ik-adapter", "registry.json");
|
|
72
|
+
this.usagePath = path.join(process.cwd(), ".ik-adapter", "usage.json");
|
|
60
73
|
this.ensureDirectory();
|
|
61
74
|
} catch (e) {
|
|
62
75
|
if (!this.hasWarnedNoFs) {
|
|
@@ -91,8 +104,13 @@ var Registry = class _Registry {
|
|
|
91
104
|
if (!fs || !this.registryPath) return {};
|
|
92
105
|
try {
|
|
93
106
|
if (fs.existsSync(this.registryPath)) {
|
|
94
|
-
const
|
|
95
|
-
|
|
107
|
+
const rawData = fs.readFileSync(this.registryPath, "utf8");
|
|
108
|
+
try {
|
|
109
|
+
const decoded = Buffer.from(rawData, "base64").toString("utf8");
|
|
110
|
+
return JSON.parse(decoded);
|
|
111
|
+
} catch (e) {
|
|
112
|
+
return JSON.parse(rawData);
|
|
113
|
+
}
|
|
96
114
|
}
|
|
97
115
|
} catch (error) {
|
|
98
116
|
console.error("[IK_REGISTRY] Load error:", error);
|
|
@@ -112,7 +130,9 @@ var Registry = class _Registry {
|
|
|
112
130
|
}
|
|
113
131
|
try {
|
|
114
132
|
this.ensureDirectory();
|
|
115
|
-
|
|
133
|
+
const jsonStr = JSON.stringify(data, null, 2);
|
|
134
|
+
const obfuscated = Buffer.from(jsonStr).toString("base64");
|
|
135
|
+
fs.writeFileSync(this.registryPath, obfuscated, "utf8");
|
|
116
136
|
} catch (error) {
|
|
117
137
|
if (!this.hasWarnedSaveError) {
|
|
118
138
|
console.error("\n[IK_REGISTRY] \u{1F6A8} ERROR saving registry.json. Your environment likely has a read-only filesystem (e.g. Vercel Serverless).");
|
|
@@ -143,17 +163,76 @@ var Registry = class _Registry {
|
|
|
143
163
|
delete all[instanceId];
|
|
144
164
|
this.save(all);
|
|
145
165
|
}
|
|
166
|
+
getUsageFilePath() {
|
|
167
|
+
return this.usagePath;
|
|
168
|
+
}
|
|
169
|
+
exists(filePath) {
|
|
170
|
+
return fs && fs.existsSync(filePath);
|
|
171
|
+
}
|
|
172
|
+
loadUsage() {
|
|
173
|
+
if (!fs || !this.usagePath || !fs.existsSync(this.usagePath)) return [];
|
|
174
|
+
try {
|
|
175
|
+
const raw = fs.readFileSync(this.usagePath, "utf8");
|
|
176
|
+
return JSON.parse(raw);
|
|
177
|
+
} catch (e) {
|
|
178
|
+
return [];
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
saveUsage(data) {
|
|
182
|
+
if (!fs || !this.usagePath) return;
|
|
183
|
+
try {
|
|
184
|
+
fs.writeFileSync(this.usagePath, JSON.stringify(data, null, 2), "utf8");
|
|
185
|
+
} catch (e) {
|
|
186
|
+
console.error("[IK_REGISTRY] Failed to save usage:", e);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
clearUsage() {
|
|
190
|
+
if (!fs || !this.usagePath) return;
|
|
191
|
+
try {
|
|
192
|
+
if (fs.existsSync(this.usagePath)) {
|
|
193
|
+
fs.unlinkSync(this.usagePath);
|
|
194
|
+
}
|
|
195
|
+
} catch (e) {
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// src/lib/hmac.ts
|
|
201
|
+
var import_node_crypto = __toESM(require("crypto"), 1);
|
|
202
|
+
var IKHmac = class {
|
|
203
|
+
secret;
|
|
204
|
+
constructor(secret) {
|
|
205
|
+
this.secret = secret;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Verifies that a response from the IK-Firewall server is authentic.
|
|
209
|
+
*/
|
|
210
|
+
verify(data) {
|
|
211
|
+
if (!data || !data.signature) return false;
|
|
212
|
+
const { signature, ...rest } = data;
|
|
213
|
+
const payload = JSON.stringify(rest);
|
|
214
|
+
const expectedSignature = import_node_crypto.default.createHmac("sha256", this.secret).update(payload).digest("hex");
|
|
215
|
+
return signature === expectedSignature;
|
|
216
|
+
}
|
|
146
217
|
};
|
|
147
218
|
|
|
148
219
|
// src/ConfigManager.ts
|
|
149
220
|
var ConfigManager = class {
|
|
150
221
|
config;
|
|
151
222
|
registry;
|
|
152
|
-
|
|
223
|
+
hooks;
|
|
224
|
+
constructor(initialConfig, hooks) {
|
|
153
225
|
this.config = initialConfig;
|
|
226
|
+
this.hooks = hooks;
|
|
154
227
|
this.registry = Registry.getInstance();
|
|
155
228
|
this.loadFromRegistry();
|
|
156
229
|
}
|
|
230
|
+
getRegistry() {
|
|
231
|
+
return this.registry;
|
|
232
|
+
}
|
|
233
|
+
setHooks(hooks) {
|
|
234
|
+
this.hooks = hooks;
|
|
235
|
+
}
|
|
157
236
|
loadFromRegistry() {
|
|
158
237
|
const instanceConfigs = this.registry.load();
|
|
159
238
|
this.config.instanceConfigs = {
|
|
@@ -176,32 +255,60 @@ var ConfigManager = class {
|
|
|
176
255
|
}
|
|
177
256
|
}
|
|
178
257
|
try {
|
|
179
|
-
const endpoint = this.config.centralReportEndpoint || "https://ik-firewall
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
"
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
258
|
+
const endpoint = this.config.centralReportEndpoint || "https://ik-firewall.vercel.app/api/v1/sync";
|
|
259
|
+
const instanceConfig2 = this.config.instanceConfigs?.[instanceId];
|
|
260
|
+
const registrationEmail = instanceConfig2?.ownerEmail || this.config.ownerEmail;
|
|
261
|
+
if ((!instanceConfig2?.licenseKey || instanceConfig2.licenseKey.startsWith("TRIAL-")) && registrationEmail) {
|
|
262
|
+
const success = await this.registerInstance(instanceId, registrationEmail);
|
|
263
|
+
if (success) {
|
|
264
|
+
this.hooks?.onStatus?.("\u2728 IK_SYNC: Zero-Config registration successful. License issued.");
|
|
265
|
+
return;
|
|
266
|
+
} else {
|
|
267
|
+
this.hooks?.onStatus?.("\u26A0\uFE0F IK_SYNC: Auto-registration failed. Continuing with local trial.");
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
this.hooks?.onStatus?.(`\u{1F4E1} IK_SYNC: Heartbeat to ${endpoint}...`);
|
|
271
|
+
const response = await fetch(`${endpoint}?licenseKey=${instanceConfig2?.licenseKey || ""}&instanceId=${instanceId}&version=2.2.0`);
|
|
272
|
+
if (response.ok) {
|
|
273
|
+
const data = await response.json();
|
|
274
|
+
if (this.config.hmacSecret) {
|
|
275
|
+
const verifier = new IKHmac(this.config.hmacSecret);
|
|
276
|
+
if (!verifier.verify(data)) {
|
|
277
|
+
console.error("[IK_SYNC] \u{1F6A8} Signature verification failed! Remote config rejected.");
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
this.setInstanceConfig(instanceId, {
|
|
282
|
+
billingStatus: data.billingStatus,
|
|
283
|
+
isVerified: data.isVerified,
|
|
284
|
+
pricing: data.pricing,
|
|
285
|
+
lastSyncDate: now.toISOString()
|
|
286
|
+
});
|
|
287
|
+
this.hooks?.onStatus?.("\u2705 IK_SYNC: Remote configuration updated and verified.");
|
|
288
|
+
} else {
|
|
289
|
+
throw new Error(`Server responded with ${response.status}`);
|
|
290
|
+
}
|
|
291
|
+
if (!instanceConfig2?.firstUseDate) {
|
|
196
292
|
this.setInstanceConfig(instanceId, { firstUseDate: now.toISOString() });
|
|
197
293
|
}
|
|
198
294
|
} catch (error) {
|
|
199
|
-
console.error(
|
|
295
|
+
console.error(`[IK_CONFIG] Remote sync failed (${error.message}). Falling open (Fail-Open mode).`);
|
|
200
296
|
this.setInstanceConfig(instanceId, {
|
|
201
297
|
isVerified: true,
|
|
202
298
|
lastSyncDate: now.toISOString()
|
|
203
299
|
});
|
|
204
300
|
}
|
|
301
|
+
try {
|
|
302
|
+
const registry = this.registry;
|
|
303
|
+
if (registry.exists(registry.getUsageFilePath())) {
|
|
304
|
+
const aggregatedUsage = registry.loadUsage();
|
|
305
|
+
if (aggregatedUsage.length > 0) {
|
|
306
|
+
this.hooks?.onStatus?.(`\u{1F4CA} IK_SYNC: Found ${aggregatedUsage.length} pending usage reports. Preparation for Daily Flush...`);
|
|
307
|
+
this._pendingUsage = aggregatedUsage;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
} catch (e) {
|
|
311
|
+
}
|
|
205
312
|
}
|
|
206
313
|
getConfig() {
|
|
207
314
|
return { ...this.config };
|
|
@@ -242,6 +349,40 @@ var ConfigManager = class {
|
|
|
242
349
|
}
|
|
243
350
|
this.updateConfig({ plugins });
|
|
244
351
|
}
|
|
352
|
+
async registerInstance(instanceId, email) {
|
|
353
|
+
try {
|
|
354
|
+
const endpoint = (this.config.centralReportEndpoint || "https://ik-firewall.vercel.app/api/v1").replace(/\/sync$/, "") + "/register";
|
|
355
|
+
this.hooks?.onStatus?.(`\u{1F680} IK_REGISTRY: Registering new instance for ${email}...`);
|
|
356
|
+
const response = await fetch(endpoint, {
|
|
357
|
+
method: "POST",
|
|
358
|
+
headers: { "Content-Type": "application/json" },
|
|
359
|
+
body: JSON.stringify({ email, instanceId })
|
|
360
|
+
});
|
|
361
|
+
if (response.ok) {
|
|
362
|
+
const data = await response.json();
|
|
363
|
+
if (this.config.hmacSecret) {
|
|
364
|
+
const verifier = new IKHmac(this.config.hmacSecret);
|
|
365
|
+
if (!verifier.verify(data)) {
|
|
366
|
+
console.error("[IK_REGISTRY] \u{1F6A8} Registration signature mismatch. Data rejected!");
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
this.setInstanceConfig(instanceId, {
|
|
371
|
+
licenseKey: data.licenseKey,
|
|
372
|
+
billingStatus: data.status.toLowerCase(),
|
|
373
|
+
isVerified: true,
|
|
374
|
+
firstUseDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
375
|
+
pricing: data.pricing
|
|
376
|
+
});
|
|
377
|
+
this.hooks?.onStatus?.("\u2728 IK_REGISTRY: Instance registered successfully and license issued.");
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
return false;
|
|
381
|
+
} catch (error) {
|
|
382
|
+
console.error("[IK_REGISTRY] Registration failed:", error);
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
245
386
|
ensureInstanceConfig(instanceId) {
|
|
246
387
|
const all = this.registry.load();
|
|
247
388
|
if (!all[instanceId]) {
|
|
@@ -249,7 +390,9 @@ var ConfigManager = class {
|
|
|
249
390
|
balance: this.config.balance || 0.5,
|
|
250
391
|
aggressiveness: this.config.aggressiveness || 0.5,
|
|
251
392
|
isEnabled: true,
|
|
252
|
-
contextMode: "FIRST_MESSAGE"
|
|
393
|
+
contextMode: "FIRST_MESSAGE",
|
|
394
|
+
ownerEmail: this.config.ownerEmail
|
|
395
|
+
// Inherit from global if not specific
|
|
253
396
|
});
|
|
254
397
|
this.loadFromRegistry();
|
|
255
398
|
}
|
|
@@ -1328,12 +1471,6 @@ var UsageTracker = class {
|
|
|
1328
1471
|
// Immediate reporting for Edge/Stateless environments
|
|
1329
1472
|
hooks;
|
|
1330
1473
|
config;
|
|
1331
|
-
// Static pricing benchmarks (cost per 1k tokens in USD)
|
|
1332
|
-
static PRICING = {
|
|
1333
|
-
"gpt-4o": { input: 5e-3, output: 0.015 },
|
|
1334
|
-
"gpt-4o-mini": { input: 15e-5, output: 6e-4 },
|
|
1335
|
-
"local": { input: 0, output: 0 }
|
|
1336
|
-
};
|
|
1337
1474
|
constructor(config, hooks) {
|
|
1338
1475
|
this.config = config;
|
|
1339
1476
|
this.hooks = hooks;
|
|
@@ -1366,42 +1503,71 @@ var UsageTracker = class {
|
|
|
1366
1503
|
};
|
|
1367
1504
|
this.buffer.push(data);
|
|
1368
1505
|
this.hooks?.onUsageReported?.(data);
|
|
1369
|
-
|
|
1370
|
-
|
|
1506
|
+
await this.persistToLocalBuffer(data);
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* Appends usage data to the local .ik-adapter/usage.json file
|
|
1510
|
+
*/
|
|
1511
|
+
async persistToLocalBuffer(data) {
|
|
1512
|
+
try {
|
|
1513
|
+
const registry = this.config.getRegistry();
|
|
1514
|
+
const usageFile = registry.getUsageFilePath();
|
|
1515
|
+
let existingUsage = [];
|
|
1516
|
+
if (registry.exists(usageFile)) {
|
|
1517
|
+
existingUsage = registry.loadUsage();
|
|
1518
|
+
}
|
|
1519
|
+
existingUsage.push(data);
|
|
1520
|
+
registry.saveUsage(existingUsage);
|
|
1521
|
+
} catch (e) {
|
|
1522
|
+
console.error("[IK_TRACKER] Failed to persist usage to local buffer:", e);
|
|
1371
1523
|
}
|
|
1372
1524
|
}
|
|
1373
1525
|
/**
|
|
1374
1526
|
* Send buffered usage data to the central IK billing service
|
|
1375
1527
|
*/
|
|
1376
|
-
async flush() {
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
return;
|
|
1382
|
-
}
|
|
1528
|
+
async flush(aggregatedData) {
|
|
1529
|
+
const usageToFlush = aggregatedData || this.buffer;
|
|
1530
|
+
if (usageToFlush.length === 0) return;
|
|
1531
|
+
const endpoint = this.config.get("centralReportEndpoint") || "https://ik-firewall.vercel.app/api/v1/report";
|
|
1532
|
+
const hmacSecret = this.config.get("hmacSecret");
|
|
1383
1533
|
try {
|
|
1384
|
-
|
|
1385
|
-
|
|
1534
|
+
this.hooks?.onStatus?.(`\u{1F4E4} IK_TRACKER: Flushing ${usageToFlush.length} interactions to ${endpoint}...`);
|
|
1535
|
+
const reportsByInstance = {};
|
|
1536
|
+
for (const report of usageToFlush) {
|
|
1537
|
+
if (!reportsByInstance[report.instanceId]) reportsByInstance[report.instanceId] = [];
|
|
1538
|
+
reportsByInstance[report.instanceId].push(report);
|
|
1539
|
+
}
|
|
1540
|
+
for (const [instanceId, reports] of Object.entries(reportsByInstance)) {
|
|
1541
|
+
const instanceConfig = this.config.getConfig().instanceConfigs?.[instanceId];
|
|
1542
|
+
const payload = {
|
|
1543
|
+
licenseKey: instanceConfig?.licenseKey || "",
|
|
1544
|
+
instanceId,
|
|
1545
|
+
reports: reports.map((r) => ({
|
|
1546
|
+
modelName: r.model_used,
|
|
1547
|
+
tokensIn: r.input_tokens,
|
|
1548
|
+
tokensOut: r.output_tokens,
|
|
1549
|
+
tokensSaved: r.tokens_saved,
|
|
1550
|
+
date: r.timestamp
|
|
1551
|
+
}))
|
|
1552
|
+
};
|
|
1553
|
+
if (hmacSecret) {
|
|
1554
|
+
const jsonStr = JSON.stringify(payload);
|
|
1555
|
+
const crypto2 = await import("crypto");
|
|
1556
|
+
payload.signature = crypto2.createHmac("sha256", hmacSecret).update(jsonStr).digest("hex");
|
|
1557
|
+
}
|
|
1558
|
+
const response = await fetch(endpoint, {
|
|
1386
1559
|
method: "POST",
|
|
1387
1560
|
headers: { "Content-Type": "application/json" },
|
|
1388
|
-
body: JSON.stringify(
|
|
1389
|
-
instanceId: report.instanceId,
|
|
1390
|
-
model: report.model_used,
|
|
1391
|
-
inputTokens: report.input_tokens,
|
|
1392
|
-
outputTokens: report.output_tokens,
|
|
1393
|
-
optimizedTokens: report.optimized_tokens,
|
|
1394
|
-
tokensSaved: report.tokens_saved,
|
|
1395
|
-
costSaved: report.cost_saved,
|
|
1396
|
-
commissionDue: report.commission_due,
|
|
1397
|
-
cqScore: report.cq_score,
|
|
1398
|
-
routingPath: report.routingPath,
|
|
1399
|
-
clientOrigin: report.clientOrigin,
|
|
1400
|
-
timestamp: report.timestamp
|
|
1401
|
-
})
|
|
1561
|
+
body: JSON.stringify(payload)
|
|
1402
1562
|
});
|
|
1563
|
+
if (!response.ok) {
|
|
1564
|
+
console.error(`[IK_TRACKER] Failed to send aggregate for ${instanceId}: ${response.statusText}`);
|
|
1565
|
+
}
|
|
1403
1566
|
}
|
|
1404
1567
|
this.buffer = [];
|
|
1568
|
+
if (aggregatedData) {
|
|
1569
|
+
this.config.getRegistry().clearUsage();
|
|
1570
|
+
}
|
|
1405
1571
|
} catch (error) {
|
|
1406
1572
|
console.error("[IK_TRACKER] Failed to flush usage data:", error);
|
|
1407
1573
|
}
|
|
@@ -1411,6 +1577,49 @@ var UsageTracker = class {
|
|
|
1411
1577
|
}
|
|
1412
1578
|
};
|
|
1413
1579
|
|
|
1580
|
+
// src/CognitiveEngine.ts
|
|
1581
|
+
var CognitiveEngine = class {
|
|
1582
|
+
/**
|
|
1583
|
+
* Sniff Cognitive DNA (CQ Score: 0-100)
|
|
1584
|
+
* Higher score = higher quality, human-like, structured content.
|
|
1585
|
+
*/
|
|
1586
|
+
static sniffDNA(input) {
|
|
1587
|
+
if (!input || input.trim().length === 0) return 0;
|
|
1588
|
+
const length = input.length;
|
|
1589
|
+
const words = input.split(/\s+/).filter((w) => w.length > 0);
|
|
1590
|
+
const wordCount = words.length;
|
|
1591
|
+
const sentences = input.split(/[.!?]+/).filter((s) => s.trim().length > 0);
|
|
1592
|
+
const avgSentenceLength = sentences.length > 0 ? wordCount / sentences.length : 0;
|
|
1593
|
+
const sentenceVariety = sentences.length > 1 ? 10 : 0;
|
|
1594
|
+
const uniqueWords = new Set(words.map((w) => w.toLowerCase())).size;
|
|
1595
|
+
const lexicalBreadth = wordCount > 0 ? uniqueWords / wordCount * 40 : 0;
|
|
1596
|
+
const markers = (input.match(/[,;:"'()\[\]]/g) || []).length;
|
|
1597
|
+
const structuralHealth = Math.min(markers / wordCount * 100, 20);
|
|
1598
|
+
const repetitivePenalty = this.calculateRepetitivePenalty(input);
|
|
1599
|
+
let score = lexicalBreadth + structuralHealth + sentenceVariety + (avgSentenceLength > 5 ? 20 : 0);
|
|
1600
|
+
score -= repetitivePenalty;
|
|
1601
|
+
return Math.max(0, Math.min(100, score));
|
|
1602
|
+
}
|
|
1603
|
+
/**
|
|
1604
|
+
* Calculate Crystallization Threshold
|
|
1605
|
+
* Logic:
|
|
1606
|
+
* Low CQ (Noise) -> Aggressive optimization (Lower threshold, e.g. 0.6)
|
|
1607
|
+
* High CQ (Quality) -> Conservative optimization (Higher threshold, e.g. 0.9)
|
|
1608
|
+
*/
|
|
1609
|
+
static calculateThreshold(cqScore) {
|
|
1610
|
+
if (cqScore < 30) return 0.65;
|
|
1611
|
+
if (cqScore < 60) return 0.78;
|
|
1612
|
+
if (cqScore < 85) return 0.88;
|
|
1613
|
+
return 0.95;
|
|
1614
|
+
}
|
|
1615
|
+
static calculateRepetitivePenalty(input) {
|
|
1616
|
+
const chunks = input.match(/.{1,10}/g) || [];
|
|
1617
|
+
const uniqueChunks = new Set(chunks).size;
|
|
1618
|
+
const ratio = chunks.length > 10 ? uniqueChunks / chunks.length : 1;
|
|
1619
|
+
return ratio < 0.5 ? (1 - ratio) * 50 : 0;
|
|
1620
|
+
}
|
|
1621
|
+
};
|
|
1622
|
+
|
|
1414
1623
|
// src/core.ts
|
|
1415
1624
|
var IKFirewallCore = class _IKFirewallCore {
|
|
1416
1625
|
static instance;
|
|
@@ -1465,55 +1674,75 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1465
1674
|
FLUID_THRESHOLD: 4
|
|
1466
1675
|
}
|
|
1467
1676
|
};
|
|
1468
|
-
gatekeeper
|
|
1677
|
+
gatekeeper;
|
|
1469
1678
|
configManager;
|
|
1470
1679
|
sessionDNA = 0;
|
|
1471
|
-
hooks;
|
|
1472
1680
|
cloudProvider;
|
|
1473
1681
|
localProvider;
|
|
1474
1682
|
orchestrator;
|
|
1475
1683
|
usageTracker;
|
|
1684
|
+
_hooks;
|
|
1685
|
+
defaultConfig;
|
|
1476
1686
|
constructor(config, hooks, cloudProvider) {
|
|
1477
|
-
|
|
1687
|
+
this.defaultConfig = {
|
|
1478
1688
|
aggressiveness: 0.15,
|
|
1479
1689
|
forcedEfficiency: false,
|
|
1480
1690
|
precisionBias: _IKFirewallCore.CONSTANTS.PRECISION.BIAS_DEFAULT,
|
|
1481
1691
|
balance: _IKFirewallCore.CONSTANTS.TONE.STABLE_VAL,
|
|
1482
1692
|
gatekeeperEnabled: true,
|
|
1483
1693
|
locale: "en",
|
|
1484
|
-
providerMode: "hybrid",
|
|
1694
|
+
providerMode: process.env.IK_FIREWALL_MODE || "hybrid",
|
|
1485
1695
|
runtimeStrategy: "internal",
|
|
1486
|
-
localAuditEndpoint: "http://127.0.0.1:8085/v1/chat/completions",
|
|
1487
|
-
|
|
1696
|
+
localAuditEndpoint: process.env.IK_FIREWALL_LOCAL_ENDPOINT || "http://127.0.0.1:8085/v1/chat/completions",
|
|
1697
|
+
centralReportEndpoint: process.env.IK_FIREWALL_CENTRAL_ENDPOINT || "https://ik-firewall.vercel.app/api/v1/sync",
|
|
1698
|
+
ownerEmail: process.env.IK_FIREWALL_EMAIL,
|
|
1699
|
+
hmacSecret: process.env.IK_FIREWALL_SECRET,
|
|
1700
|
+
fallbackToCloudAudit: process.env.IK_FIREWALL_FALLBACK === "true" || false,
|
|
1488
1701
|
modelConfig: {
|
|
1489
1702
|
modelType: "1b"
|
|
1490
1703
|
},
|
|
1491
1704
|
plugins: []
|
|
1492
1705
|
};
|
|
1493
|
-
this.
|
|
1494
|
-
|
|
1706
|
+
this._hooks = hooks;
|
|
1707
|
+
this.configManager = new ConfigManager({ ...this.defaultConfig, ...config }, hooks);
|
|
1708
|
+
this.gatekeeper = new HeuristicGatekeeper();
|
|
1709
|
+
this.sessionDNA = _IKFirewallCore.CONSTANTS.DNA.MIN;
|
|
1495
1710
|
const activeConfig = this.configManager.getConfig();
|
|
1496
1711
|
this.localProvider = new LocalProvider(activeConfig.localAuditEndpoint);
|
|
1497
1712
|
if (cloudProvider) {
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
const
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1713
|
+
this.cloudProvider = cloudProvider instanceof BaseProvider ? cloudProvider : new OpenAIProvider(cloudProvider);
|
|
1714
|
+
} else if (process.env.OPENAI_API_KEY) {
|
|
1715
|
+
this.cloudProvider = new OpenAIProvider(async (prompt, role) => {
|
|
1716
|
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
1717
|
+
method: "POST",
|
|
1718
|
+
headers: {
|
|
1719
|
+
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
|
|
1720
|
+
"Content-Type": "application/json"
|
|
1721
|
+
},
|
|
1722
|
+
body: JSON.stringify({
|
|
1723
|
+
model: role === "audit_layer" ? "gpt-4o-mini" : "gpt-4o",
|
|
1724
|
+
messages: [{ role: "user", content: prompt }],
|
|
1725
|
+
temperature: 0.1
|
|
1726
|
+
})
|
|
1727
|
+
});
|
|
1728
|
+
if (!response.ok) throw new Error(`OpenAI API Error: ${response.statusText}`);
|
|
1729
|
+
const data = await response.json();
|
|
1730
|
+
return {
|
|
1731
|
+
content: data.choices[0].message.content,
|
|
1732
|
+
usage: data.usage
|
|
1733
|
+
};
|
|
1734
|
+
});
|
|
1514
1735
|
}
|
|
1515
1736
|
this.orchestrator = new Orchestrator(this.configManager);
|
|
1516
|
-
this.usageTracker = new UsageTracker(this.configManager, this.
|
|
1737
|
+
this.usageTracker = new UsageTracker(this.configManager, this._hooks);
|
|
1738
|
+
}
|
|
1739
|
+
get hooks() {
|
|
1740
|
+
return this._hooks;
|
|
1741
|
+
}
|
|
1742
|
+
set hooks(newHooks) {
|
|
1743
|
+
this._hooks = newHooks;
|
|
1744
|
+
this.configManager.setHooks(newHooks);
|
|
1745
|
+
this.usageTracker.hooks = newHooks;
|
|
1517
1746
|
}
|
|
1518
1747
|
static getInstance(config, hooks) {
|
|
1519
1748
|
if (!_IKFirewallCore.instance) {
|
|
@@ -1625,7 +1854,14 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1625
1854
|
async analyze(input, provider, personaName = "professional", locale, instanceId) {
|
|
1626
1855
|
if (instanceId) {
|
|
1627
1856
|
this.configManager.ensureInstanceConfig(instanceId);
|
|
1628
|
-
|
|
1857
|
+
const syncPromise = this.configManager.syncRemoteConfig(instanceId).then(async () => {
|
|
1858
|
+
const pendingUsage = this.configManager._pendingUsage;
|
|
1859
|
+
if (pendingUsage && pendingUsage.length > 0) {
|
|
1860
|
+
await this.usageTracker.flush(pendingUsage);
|
|
1861
|
+
this.configManager._pendingUsage = null;
|
|
1862
|
+
}
|
|
1863
|
+
});
|
|
1864
|
+
await syncPromise;
|
|
1629
1865
|
}
|
|
1630
1866
|
const mergedConfig = this.configManager.getMergedConfig(instanceId);
|
|
1631
1867
|
if (instanceId && mergedConfig?.isVerified === false) {
|
|
@@ -1695,10 +1931,17 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1695
1931
|
throw e;
|
|
1696
1932
|
}
|
|
1697
1933
|
}
|
|
1698
|
-
|
|
1934
|
+
const cqScore = CognitiveEngine.sniffDNA(input);
|
|
1935
|
+
metrics.dm = Math.max(metrics.dm, cqScore / 10);
|
|
1936
|
+
this.applyHardening(input, metrics, activeLocale);
|
|
1699
1937
|
this.hooks?.onAuditComplete?.(metrics);
|
|
1700
1938
|
return metrics;
|
|
1701
1939
|
}
|
|
1940
|
+
applyHardening(input, metrics, locale = "en") {
|
|
1941
|
+
const archetype = metrics.semanticInsights?.archetype || "DYNAMIC";
|
|
1942
|
+
const domain = metrics.semanticInsights?.detectedDomain || "GENERAL";
|
|
1943
|
+
this.setSessionDNA(this.sessionDNA + 5);
|
|
1944
|
+
}
|
|
1702
1945
|
getEmptyMetrics() {
|
|
1703
1946
|
return {
|
|
1704
1947
|
dm: 0,
|
|
@@ -1750,28 +1993,6 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1750
1993
|
inputLength: input.length
|
|
1751
1994
|
};
|
|
1752
1995
|
}
|
|
1753
|
-
sniffDNA(input, metrics, locale = "en") {
|
|
1754
|
-
const archetype = metrics.semanticInsights?.archetype || "DYNAMIC";
|
|
1755
|
-
const domain = metrics.semanticInsights?.detectedDomain || "GENERAL";
|
|
1756
|
-
const meta = Dictionaries.meta[locale] || Dictionaries.meta.en;
|
|
1757
|
-
const patterns = (meta.system_prompt_patterns || "").split(",").map((p) => p.trim()).filter((p) => p.length > 0);
|
|
1758
|
-
const isSystemPrompt = patterns.some((kw) => input.toLowerCase().includes(kw));
|
|
1759
|
-
let dnaShift = 0;
|
|
1760
|
-
if (archetype === "CRYSTAL") {
|
|
1761
|
-
dnaShift += _IKFirewallCore.CONSTANTS.DNA.HARDENING_MODERATE;
|
|
1762
|
-
} else if (archetype === "FLUID") {
|
|
1763
|
-
dnaShift -= _IKFirewallCore.CONSTANTS.DNA.SOFTENING_STEP;
|
|
1764
|
-
} else if (archetype === "NEURAL") {
|
|
1765
|
-
dnaShift -= _IKFirewallCore.CONSTANTS.DNA.SOFTENING_STEP / 2;
|
|
1766
|
-
}
|
|
1767
|
-
if (["LEGAL", "MEDICAL", "FINANCE", "CONSTRUCTION", "ENGINEERING"].includes(domain)) {
|
|
1768
|
-
dnaShift += _IKFirewallCore.CONSTANTS.DNA.HARDENING_DOMAIN;
|
|
1769
|
-
}
|
|
1770
|
-
if (isSystemPrompt) {
|
|
1771
|
-
dnaShift += _IKFirewallCore.CONSTANTS.DNA.HARDENING_MODERATE;
|
|
1772
|
-
}
|
|
1773
|
-
this.setSessionDNA(this.sessionDNA + dnaShift);
|
|
1774
|
-
}
|
|
1775
1996
|
async analyzeAIAssisted(input, provider, personaName = "professional", instanceId, configOverride) {
|
|
1776
1997
|
if (instanceId) {
|
|
1777
1998
|
this.configManager.ensureInstanceConfig(instanceId);
|
|
@@ -2022,11 +2243,13 @@ Any action outside this scope MUST be rejected and flagged as a boundary violati
|
|
|
2022
2243
|
this.hooks?.onStatus?.(`\u{1F6E1}\uFE0F IK_CRYSTALLIZE: Precision domain detected (${domain}). Relaxing noise reduction...`);
|
|
2023
2244
|
archetypeModifier = -0.3;
|
|
2024
2245
|
}
|
|
2246
|
+
const cqScore = CognitiveEngine.sniffDNA(input);
|
|
2247
|
+
const cognitiveThreshold = CognitiveEngine.calculateThreshold(cqScore);
|
|
2025
2248
|
const threshold = Math.min(
|
|
2026
2249
|
_IKFirewallCore.CONSTANTS.AI.THRESHOLD_MAX,
|
|
2027
2250
|
Math.max(
|
|
2028
2251
|
_IKFirewallCore.CONSTANTS.AI.THRESHOLD_MIN,
|
|
2029
|
-
|
|
2252
|
+
cognitiveThreshold + archetypeModifier - tolerance * 0.1
|
|
2030
2253
|
)
|
|
2031
2254
|
);
|
|
2032
2255
|
const lengthRatio = blueprint ? blueprint.length / input.length : 1;
|
package/dist/index.d.cts
CHANGED
|
@@ -48,6 +48,8 @@ interface IKConfig {
|
|
|
48
48
|
isVerified?: boolean;
|
|
49
49
|
firstUseDate?: string;
|
|
50
50
|
lastSyncDate?: string;
|
|
51
|
+
ownerEmail?: string;
|
|
52
|
+
hmacSecret?: string;
|
|
51
53
|
pricing?: Record<string, {
|
|
52
54
|
input: number;
|
|
53
55
|
output: number;
|
|
@@ -304,12 +306,15 @@ declare class IKFirewallCore {
|
|
|
304
306
|
private gatekeeper;
|
|
305
307
|
private configManager;
|
|
306
308
|
private sessionDNA;
|
|
307
|
-
hooks?: IKHooks;
|
|
308
309
|
private cloudProvider?;
|
|
309
310
|
private localProvider;
|
|
310
311
|
private orchestrator;
|
|
311
312
|
private usageTracker;
|
|
313
|
+
private _hooks?;
|
|
314
|
+
private defaultConfig;
|
|
312
315
|
constructor(config?: Partial<IKConfig>, hooks?: IKHooks, cloudProvider?: AIProvider | BaseProvider);
|
|
316
|
+
get hooks(): IKHooks | undefined;
|
|
317
|
+
set hooks(newHooks: IKHooks | undefined);
|
|
313
318
|
static getInstance(config?: Partial<IKConfig>, hooks?: IKHooks): IKFirewallCore;
|
|
314
319
|
setConfig(newConfig: Partial<IKConfig>): void;
|
|
315
320
|
getConfig(): IKConfig;
|
|
@@ -355,9 +360,9 @@ declare class IKFirewallCore {
|
|
|
355
360
|
* Primary Analysis Entry Point
|
|
356
361
|
*/
|
|
357
362
|
analyze(input: string, provider?: AIProvider | BaseProvider, personaName?: string, locale?: string, instanceId?: string): Promise<IKMetrics>;
|
|
363
|
+
private applyHardening;
|
|
358
364
|
private getEmptyMetrics;
|
|
359
365
|
private createHeuristicMetrics;
|
|
360
|
-
private sniffDNA;
|
|
361
366
|
analyzeAIAssisted(input: string, provider?: AIProvider | BaseProvider, personaName?: string, instanceId?: string, configOverride?: Partial<IKConfig>): Promise<IKMetrics>;
|
|
362
367
|
private calculateDNARank;
|
|
363
368
|
private constructAuditPrompt;
|
package/dist/index.d.ts
CHANGED
|
@@ -48,6 +48,8 @@ interface IKConfig {
|
|
|
48
48
|
isVerified?: boolean;
|
|
49
49
|
firstUseDate?: string;
|
|
50
50
|
lastSyncDate?: string;
|
|
51
|
+
ownerEmail?: string;
|
|
52
|
+
hmacSecret?: string;
|
|
51
53
|
pricing?: Record<string, {
|
|
52
54
|
input: number;
|
|
53
55
|
output: number;
|
|
@@ -304,12 +306,15 @@ declare class IKFirewallCore {
|
|
|
304
306
|
private gatekeeper;
|
|
305
307
|
private configManager;
|
|
306
308
|
private sessionDNA;
|
|
307
|
-
hooks?: IKHooks;
|
|
308
309
|
private cloudProvider?;
|
|
309
310
|
private localProvider;
|
|
310
311
|
private orchestrator;
|
|
311
312
|
private usageTracker;
|
|
313
|
+
private _hooks?;
|
|
314
|
+
private defaultConfig;
|
|
312
315
|
constructor(config?: Partial<IKConfig>, hooks?: IKHooks, cloudProvider?: AIProvider | BaseProvider);
|
|
316
|
+
get hooks(): IKHooks | undefined;
|
|
317
|
+
set hooks(newHooks: IKHooks | undefined);
|
|
313
318
|
static getInstance(config?: Partial<IKConfig>, hooks?: IKHooks): IKFirewallCore;
|
|
314
319
|
setConfig(newConfig: Partial<IKConfig>): void;
|
|
315
320
|
getConfig(): IKConfig;
|
|
@@ -355,9 +360,9 @@ declare class IKFirewallCore {
|
|
|
355
360
|
* Primary Analysis Entry Point
|
|
356
361
|
*/
|
|
357
362
|
analyze(input: string, provider?: AIProvider | BaseProvider, personaName?: string, locale?: string, instanceId?: string): Promise<IKMetrics>;
|
|
363
|
+
private applyHardening;
|
|
358
364
|
private getEmptyMetrics;
|
|
359
365
|
private createHeuristicMetrics;
|
|
360
|
-
private sniffDNA;
|
|
361
366
|
analyzeAIAssisted(input: string, provider?: AIProvider | BaseProvider, personaName?: string, instanceId?: string, configOverride?: Partial<IKConfig>): Promise<IKMetrics>;
|
|
362
367
|
private calculateDNARank;
|
|
363
368
|
private constructAuditPrompt;
|
package/dist/index.js
CHANGED
|
@@ -16,15 +16,18 @@ if (typeof window === "undefined") {
|
|
|
16
16
|
var Registry = class _Registry {
|
|
17
17
|
static instance;
|
|
18
18
|
registryPath;
|
|
19
|
+
usagePath;
|
|
19
20
|
hasWarnedNoFs = false;
|
|
20
21
|
hasWarnedSaveError = false;
|
|
21
22
|
constructor() {
|
|
22
23
|
this.registryPath = "";
|
|
24
|
+
this.usagePath = "";
|
|
23
25
|
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
24
26
|
try {
|
|
25
27
|
fs = __require("fs");
|
|
26
28
|
path = __require("path");
|
|
27
29
|
this.registryPath = path.join(process.cwd(), ".ik-adapter", "registry.json");
|
|
30
|
+
this.usagePath = path.join(process.cwd(), ".ik-adapter", "usage.json");
|
|
28
31
|
this.ensureDirectory();
|
|
29
32
|
} catch (e) {
|
|
30
33
|
if (!this.hasWarnedNoFs) {
|
|
@@ -59,8 +62,13 @@ var Registry = class _Registry {
|
|
|
59
62
|
if (!fs || !this.registryPath) return {};
|
|
60
63
|
try {
|
|
61
64
|
if (fs.existsSync(this.registryPath)) {
|
|
62
|
-
const
|
|
63
|
-
|
|
65
|
+
const rawData = fs.readFileSync(this.registryPath, "utf8");
|
|
66
|
+
try {
|
|
67
|
+
const decoded = Buffer.from(rawData, "base64").toString("utf8");
|
|
68
|
+
return JSON.parse(decoded);
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return JSON.parse(rawData);
|
|
71
|
+
}
|
|
64
72
|
}
|
|
65
73
|
} catch (error) {
|
|
66
74
|
console.error("[IK_REGISTRY] Load error:", error);
|
|
@@ -80,7 +88,9 @@ var Registry = class _Registry {
|
|
|
80
88
|
}
|
|
81
89
|
try {
|
|
82
90
|
this.ensureDirectory();
|
|
83
|
-
|
|
91
|
+
const jsonStr = JSON.stringify(data, null, 2);
|
|
92
|
+
const obfuscated = Buffer.from(jsonStr).toString("base64");
|
|
93
|
+
fs.writeFileSync(this.registryPath, obfuscated, "utf8");
|
|
84
94
|
} catch (error) {
|
|
85
95
|
if (!this.hasWarnedSaveError) {
|
|
86
96
|
console.error("\n[IK_REGISTRY] \u{1F6A8} ERROR saving registry.json. Your environment likely has a read-only filesystem (e.g. Vercel Serverless).");
|
|
@@ -111,17 +121,76 @@ var Registry = class _Registry {
|
|
|
111
121
|
delete all[instanceId];
|
|
112
122
|
this.save(all);
|
|
113
123
|
}
|
|
124
|
+
getUsageFilePath() {
|
|
125
|
+
return this.usagePath;
|
|
126
|
+
}
|
|
127
|
+
exists(filePath) {
|
|
128
|
+
return fs && fs.existsSync(filePath);
|
|
129
|
+
}
|
|
130
|
+
loadUsage() {
|
|
131
|
+
if (!fs || !this.usagePath || !fs.existsSync(this.usagePath)) return [];
|
|
132
|
+
try {
|
|
133
|
+
const raw = fs.readFileSync(this.usagePath, "utf8");
|
|
134
|
+
return JSON.parse(raw);
|
|
135
|
+
} catch (e) {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
saveUsage(data) {
|
|
140
|
+
if (!fs || !this.usagePath) return;
|
|
141
|
+
try {
|
|
142
|
+
fs.writeFileSync(this.usagePath, JSON.stringify(data, null, 2), "utf8");
|
|
143
|
+
} catch (e) {
|
|
144
|
+
console.error("[IK_REGISTRY] Failed to save usage:", e);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
clearUsage() {
|
|
148
|
+
if (!fs || !this.usagePath) return;
|
|
149
|
+
try {
|
|
150
|
+
if (fs.existsSync(this.usagePath)) {
|
|
151
|
+
fs.unlinkSync(this.usagePath);
|
|
152
|
+
}
|
|
153
|
+
} catch (e) {
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// src/lib/hmac.ts
|
|
159
|
+
import crypto from "crypto";
|
|
160
|
+
var IKHmac = class {
|
|
161
|
+
secret;
|
|
162
|
+
constructor(secret) {
|
|
163
|
+
this.secret = secret;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Verifies that a response from the IK-Firewall server is authentic.
|
|
167
|
+
*/
|
|
168
|
+
verify(data) {
|
|
169
|
+
if (!data || !data.signature) return false;
|
|
170
|
+
const { signature, ...rest } = data;
|
|
171
|
+
const payload = JSON.stringify(rest);
|
|
172
|
+
const expectedSignature = crypto.createHmac("sha256", this.secret).update(payload).digest("hex");
|
|
173
|
+
return signature === expectedSignature;
|
|
174
|
+
}
|
|
114
175
|
};
|
|
115
176
|
|
|
116
177
|
// src/ConfigManager.ts
|
|
117
178
|
var ConfigManager = class {
|
|
118
179
|
config;
|
|
119
180
|
registry;
|
|
120
|
-
|
|
181
|
+
hooks;
|
|
182
|
+
constructor(initialConfig, hooks) {
|
|
121
183
|
this.config = initialConfig;
|
|
184
|
+
this.hooks = hooks;
|
|
122
185
|
this.registry = Registry.getInstance();
|
|
123
186
|
this.loadFromRegistry();
|
|
124
187
|
}
|
|
188
|
+
getRegistry() {
|
|
189
|
+
return this.registry;
|
|
190
|
+
}
|
|
191
|
+
setHooks(hooks) {
|
|
192
|
+
this.hooks = hooks;
|
|
193
|
+
}
|
|
125
194
|
loadFromRegistry() {
|
|
126
195
|
const instanceConfigs = this.registry.load();
|
|
127
196
|
this.config.instanceConfigs = {
|
|
@@ -144,32 +213,60 @@ var ConfigManager = class {
|
|
|
144
213
|
}
|
|
145
214
|
}
|
|
146
215
|
try {
|
|
147
|
-
const endpoint = this.config.centralReportEndpoint || "https://ik-firewall
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
"
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
216
|
+
const endpoint = this.config.centralReportEndpoint || "https://ik-firewall.vercel.app/api/v1/sync";
|
|
217
|
+
const instanceConfig2 = this.config.instanceConfigs?.[instanceId];
|
|
218
|
+
const registrationEmail = instanceConfig2?.ownerEmail || this.config.ownerEmail;
|
|
219
|
+
if ((!instanceConfig2?.licenseKey || instanceConfig2.licenseKey.startsWith("TRIAL-")) && registrationEmail) {
|
|
220
|
+
const success = await this.registerInstance(instanceId, registrationEmail);
|
|
221
|
+
if (success) {
|
|
222
|
+
this.hooks?.onStatus?.("\u2728 IK_SYNC: Zero-Config registration successful. License issued.");
|
|
223
|
+
return;
|
|
224
|
+
} else {
|
|
225
|
+
this.hooks?.onStatus?.("\u26A0\uFE0F IK_SYNC: Auto-registration failed. Continuing with local trial.");
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
this.hooks?.onStatus?.(`\u{1F4E1} IK_SYNC: Heartbeat to ${endpoint}...`);
|
|
229
|
+
const response = await fetch(`${endpoint}?licenseKey=${instanceConfig2?.licenseKey || ""}&instanceId=${instanceId}&version=2.2.0`);
|
|
230
|
+
if (response.ok) {
|
|
231
|
+
const data = await response.json();
|
|
232
|
+
if (this.config.hmacSecret) {
|
|
233
|
+
const verifier = new IKHmac(this.config.hmacSecret);
|
|
234
|
+
if (!verifier.verify(data)) {
|
|
235
|
+
console.error("[IK_SYNC] \u{1F6A8} Signature verification failed! Remote config rejected.");
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
this.setInstanceConfig(instanceId, {
|
|
240
|
+
billingStatus: data.billingStatus,
|
|
241
|
+
isVerified: data.isVerified,
|
|
242
|
+
pricing: data.pricing,
|
|
243
|
+
lastSyncDate: now.toISOString()
|
|
244
|
+
});
|
|
245
|
+
this.hooks?.onStatus?.("\u2705 IK_SYNC: Remote configuration updated and verified.");
|
|
246
|
+
} else {
|
|
247
|
+
throw new Error(`Server responded with ${response.status}`);
|
|
248
|
+
}
|
|
249
|
+
if (!instanceConfig2?.firstUseDate) {
|
|
164
250
|
this.setInstanceConfig(instanceId, { firstUseDate: now.toISOString() });
|
|
165
251
|
}
|
|
166
252
|
} catch (error) {
|
|
167
|
-
console.error(
|
|
253
|
+
console.error(`[IK_CONFIG] Remote sync failed (${error.message}). Falling open (Fail-Open mode).`);
|
|
168
254
|
this.setInstanceConfig(instanceId, {
|
|
169
255
|
isVerified: true,
|
|
170
256
|
lastSyncDate: now.toISOString()
|
|
171
257
|
});
|
|
172
258
|
}
|
|
259
|
+
try {
|
|
260
|
+
const registry = this.registry;
|
|
261
|
+
if (registry.exists(registry.getUsageFilePath())) {
|
|
262
|
+
const aggregatedUsage = registry.loadUsage();
|
|
263
|
+
if (aggregatedUsage.length > 0) {
|
|
264
|
+
this.hooks?.onStatus?.(`\u{1F4CA} IK_SYNC: Found ${aggregatedUsage.length} pending usage reports. Preparation for Daily Flush...`);
|
|
265
|
+
this._pendingUsage = aggregatedUsage;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
} catch (e) {
|
|
269
|
+
}
|
|
173
270
|
}
|
|
174
271
|
getConfig() {
|
|
175
272
|
return { ...this.config };
|
|
@@ -210,6 +307,40 @@ var ConfigManager = class {
|
|
|
210
307
|
}
|
|
211
308
|
this.updateConfig({ plugins });
|
|
212
309
|
}
|
|
310
|
+
async registerInstance(instanceId, email) {
|
|
311
|
+
try {
|
|
312
|
+
const endpoint = (this.config.centralReportEndpoint || "https://ik-firewall.vercel.app/api/v1").replace(/\/sync$/, "") + "/register";
|
|
313
|
+
this.hooks?.onStatus?.(`\u{1F680} IK_REGISTRY: Registering new instance for ${email}...`);
|
|
314
|
+
const response = await fetch(endpoint, {
|
|
315
|
+
method: "POST",
|
|
316
|
+
headers: { "Content-Type": "application/json" },
|
|
317
|
+
body: JSON.stringify({ email, instanceId })
|
|
318
|
+
});
|
|
319
|
+
if (response.ok) {
|
|
320
|
+
const data = await response.json();
|
|
321
|
+
if (this.config.hmacSecret) {
|
|
322
|
+
const verifier = new IKHmac(this.config.hmacSecret);
|
|
323
|
+
if (!verifier.verify(data)) {
|
|
324
|
+
console.error("[IK_REGISTRY] \u{1F6A8} Registration signature mismatch. Data rejected!");
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
this.setInstanceConfig(instanceId, {
|
|
329
|
+
licenseKey: data.licenseKey,
|
|
330
|
+
billingStatus: data.status.toLowerCase(),
|
|
331
|
+
isVerified: true,
|
|
332
|
+
firstUseDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
333
|
+
pricing: data.pricing
|
|
334
|
+
});
|
|
335
|
+
this.hooks?.onStatus?.("\u2728 IK_REGISTRY: Instance registered successfully and license issued.");
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
return false;
|
|
339
|
+
} catch (error) {
|
|
340
|
+
console.error("[IK_REGISTRY] Registration failed:", error);
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
213
344
|
ensureInstanceConfig(instanceId) {
|
|
214
345
|
const all = this.registry.load();
|
|
215
346
|
if (!all[instanceId]) {
|
|
@@ -217,7 +348,9 @@ var ConfigManager = class {
|
|
|
217
348
|
balance: this.config.balance || 0.5,
|
|
218
349
|
aggressiveness: this.config.aggressiveness || 0.5,
|
|
219
350
|
isEnabled: true,
|
|
220
|
-
contextMode: "FIRST_MESSAGE"
|
|
351
|
+
contextMode: "FIRST_MESSAGE",
|
|
352
|
+
ownerEmail: this.config.ownerEmail
|
|
353
|
+
// Inherit from global if not specific
|
|
221
354
|
});
|
|
222
355
|
this.loadFromRegistry();
|
|
223
356
|
}
|
|
@@ -1296,12 +1429,6 @@ var UsageTracker = class {
|
|
|
1296
1429
|
// Immediate reporting for Edge/Stateless environments
|
|
1297
1430
|
hooks;
|
|
1298
1431
|
config;
|
|
1299
|
-
// Static pricing benchmarks (cost per 1k tokens in USD)
|
|
1300
|
-
static PRICING = {
|
|
1301
|
-
"gpt-4o": { input: 5e-3, output: 0.015 },
|
|
1302
|
-
"gpt-4o-mini": { input: 15e-5, output: 6e-4 },
|
|
1303
|
-
"local": { input: 0, output: 0 }
|
|
1304
|
-
};
|
|
1305
1432
|
constructor(config, hooks) {
|
|
1306
1433
|
this.config = config;
|
|
1307
1434
|
this.hooks = hooks;
|
|
@@ -1334,42 +1461,71 @@ var UsageTracker = class {
|
|
|
1334
1461
|
};
|
|
1335
1462
|
this.buffer.push(data);
|
|
1336
1463
|
this.hooks?.onUsageReported?.(data);
|
|
1337
|
-
|
|
1338
|
-
|
|
1464
|
+
await this.persistToLocalBuffer(data);
|
|
1465
|
+
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Appends usage data to the local .ik-adapter/usage.json file
|
|
1468
|
+
*/
|
|
1469
|
+
async persistToLocalBuffer(data) {
|
|
1470
|
+
try {
|
|
1471
|
+
const registry = this.config.getRegistry();
|
|
1472
|
+
const usageFile = registry.getUsageFilePath();
|
|
1473
|
+
let existingUsage = [];
|
|
1474
|
+
if (registry.exists(usageFile)) {
|
|
1475
|
+
existingUsage = registry.loadUsage();
|
|
1476
|
+
}
|
|
1477
|
+
existingUsage.push(data);
|
|
1478
|
+
registry.saveUsage(existingUsage);
|
|
1479
|
+
} catch (e) {
|
|
1480
|
+
console.error("[IK_TRACKER] Failed to persist usage to local buffer:", e);
|
|
1339
1481
|
}
|
|
1340
1482
|
}
|
|
1341
1483
|
/**
|
|
1342
1484
|
* Send buffered usage data to the central IK billing service
|
|
1343
1485
|
*/
|
|
1344
|
-
async flush() {
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
return;
|
|
1350
|
-
}
|
|
1486
|
+
async flush(aggregatedData) {
|
|
1487
|
+
const usageToFlush = aggregatedData || this.buffer;
|
|
1488
|
+
if (usageToFlush.length === 0) return;
|
|
1489
|
+
const endpoint = this.config.get("centralReportEndpoint") || "https://ik-firewall.vercel.app/api/v1/report";
|
|
1490
|
+
const hmacSecret = this.config.get("hmacSecret");
|
|
1351
1491
|
try {
|
|
1352
|
-
|
|
1353
|
-
|
|
1492
|
+
this.hooks?.onStatus?.(`\u{1F4E4} IK_TRACKER: Flushing ${usageToFlush.length} interactions to ${endpoint}...`);
|
|
1493
|
+
const reportsByInstance = {};
|
|
1494
|
+
for (const report of usageToFlush) {
|
|
1495
|
+
if (!reportsByInstance[report.instanceId]) reportsByInstance[report.instanceId] = [];
|
|
1496
|
+
reportsByInstance[report.instanceId].push(report);
|
|
1497
|
+
}
|
|
1498
|
+
for (const [instanceId, reports] of Object.entries(reportsByInstance)) {
|
|
1499
|
+
const instanceConfig = this.config.getConfig().instanceConfigs?.[instanceId];
|
|
1500
|
+
const payload = {
|
|
1501
|
+
licenseKey: instanceConfig?.licenseKey || "",
|
|
1502
|
+
instanceId,
|
|
1503
|
+
reports: reports.map((r) => ({
|
|
1504
|
+
modelName: r.model_used,
|
|
1505
|
+
tokensIn: r.input_tokens,
|
|
1506
|
+
tokensOut: r.output_tokens,
|
|
1507
|
+
tokensSaved: r.tokens_saved,
|
|
1508
|
+
date: r.timestamp
|
|
1509
|
+
}))
|
|
1510
|
+
};
|
|
1511
|
+
if (hmacSecret) {
|
|
1512
|
+
const jsonStr = JSON.stringify(payload);
|
|
1513
|
+
const crypto2 = await import("crypto");
|
|
1514
|
+
payload.signature = crypto2.createHmac("sha256", hmacSecret).update(jsonStr).digest("hex");
|
|
1515
|
+
}
|
|
1516
|
+
const response = await fetch(endpoint, {
|
|
1354
1517
|
method: "POST",
|
|
1355
1518
|
headers: { "Content-Type": "application/json" },
|
|
1356
|
-
body: JSON.stringify(
|
|
1357
|
-
instanceId: report.instanceId,
|
|
1358
|
-
model: report.model_used,
|
|
1359
|
-
inputTokens: report.input_tokens,
|
|
1360
|
-
outputTokens: report.output_tokens,
|
|
1361
|
-
optimizedTokens: report.optimized_tokens,
|
|
1362
|
-
tokensSaved: report.tokens_saved,
|
|
1363
|
-
costSaved: report.cost_saved,
|
|
1364
|
-
commissionDue: report.commission_due,
|
|
1365
|
-
cqScore: report.cq_score,
|
|
1366
|
-
routingPath: report.routingPath,
|
|
1367
|
-
clientOrigin: report.clientOrigin,
|
|
1368
|
-
timestamp: report.timestamp
|
|
1369
|
-
})
|
|
1519
|
+
body: JSON.stringify(payload)
|
|
1370
1520
|
});
|
|
1521
|
+
if (!response.ok) {
|
|
1522
|
+
console.error(`[IK_TRACKER] Failed to send aggregate for ${instanceId}: ${response.statusText}`);
|
|
1523
|
+
}
|
|
1371
1524
|
}
|
|
1372
1525
|
this.buffer = [];
|
|
1526
|
+
if (aggregatedData) {
|
|
1527
|
+
this.config.getRegistry().clearUsage();
|
|
1528
|
+
}
|
|
1373
1529
|
} catch (error) {
|
|
1374
1530
|
console.error("[IK_TRACKER] Failed to flush usage data:", error);
|
|
1375
1531
|
}
|
|
@@ -1379,6 +1535,49 @@ var UsageTracker = class {
|
|
|
1379
1535
|
}
|
|
1380
1536
|
};
|
|
1381
1537
|
|
|
1538
|
+
// src/CognitiveEngine.ts
|
|
1539
|
+
var CognitiveEngine = class {
|
|
1540
|
+
/**
|
|
1541
|
+
* Sniff Cognitive DNA (CQ Score: 0-100)
|
|
1542
|
+
* Higher score = higher quality, human-like, structured content.
|
|
1543
|
+
*/
|
|
1544
|
+
static sniffDNA(input) {
|
|
1545
|
+
if (!input || input.trim().length === 0) return 0;
|
|
1546
|
+
const length = input.length;
|
|
1547
|
+
const words = input.split(/\s+/).filter((w) => w.length > 0);
|
|
1548
|
+
const wordCount = words.length;
|
|
1549
|
+
const sentences = input.split(/[.!?]+/).filter((s) => s.trim().length > 0);
|
|
1550
|
+
const avgSentenceLength = sentences.length > 0 ? wordCount / sentences.length : 0;
|
|
1551
|
+
const sentenceVariety = sentences.length > 1 ? 10 : 0;
|
|
1552
|
+
const uniqueWords = new Set(words.map((w) => w.toLowerCase())).size;
|
|
1553
|
+
const lexicalBreadth = wordCount > 0 ? uniqueWords / wordCount * 40 : 0;
|
|
1554
|
+
const markers = (input.match(/[,;:"'()\[\]]/g) || []).length;
|
|
1555
|
+
const structuralHealth = Math.min(markers / wordCount * 100, 20);
|
|
1556
|
+
const repetitivePenalty = this.calculateRepetitivePenalty(input);
|
|
1557
|
+
let score = lexicalBreadth + structuralHealth + sentenceVariety + (avgSentenceLength > 5 ? 20 : 0);
|
|
1558
|
+
score -= repetitivePenalty;
|
|
1559
|
+
return Math.max(0, Math.min(100, score));
|
|
1560
|
+
}
|
|
1561
|
+
/**
|
|
1562
|
+
* Calculate Crystallization Threshold
|
|
1563
|
+
* Logic:
|
|
1564
|
+
* Low CQ (Noise) -> Aggressive optimization (Lower threshold, e.g. 0.6)
|
|
1565
|
+
* High CQ (Quality) -> Conservative optimization (Higher threshold, e.g. 0.9)
|
|
1566
|
+
*/
|
|
1567
|
+
static calculateThreshold(cqScore) {
|
|
1568
|
+
if (cqScore < 30) return 0.65;
|
|
1569
|
+
if (cqScore < 60) return 0.78;
|
|
1570
|
+
if (cqScore < 85) return 0.88;
|
|
1571
|
+
return 0.95;
|
|
1572
|
+
}
|
|
1573
|
+
static calculateRepetitivePenalty(input) {
|
|
1574
|
+
const chunks = input.match(/.{1,10}/g) || [];
|
|
1575
|
+
const uniqueChunks = new Set(chunks).size;
|
|
1576
|
+
const ratio = chunks.length > 10 ? uniqueChunks / chunks.length : 1;
|
|
1577
|
+
return ratio < 0.5 ? (1 - ratio) * 50 : 0;
|
|
1578
|
+
}
|
|
1579
|
+
};
|
|
1580
|
+
|
|
1382
1581
|
// src/core.ts
|
|
1383
1582
|
var IKFirewallCore = class _IKFirewallCore {
|
|
1384
1583
|
static instance;
|
|
@@ -1433,55 +1632,75 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1433
1632
|
FLUID_THRESHOLD: 4
|
|
1434
1633
|
}
|
|
1435
1634
|
};
|
|
1436
|
-
gatekeeper
|
|
1635
|
+
gatekeeper;
|
|
1437
1636
|
configManager;
|
|
1438
1637
|
sessionDNA = 0;
|
|
1439
|
-
hooks;
|
|
1440
1638
|
cloudProvider;
|
|
1441
1639
|
localProvider;
|
|
1442
1640
|
orchestrator;
|
|
1443
1641
|
usageTracker;
|
|
1642
|
+
_hooks;
|
|
1643
|
+
defaultConfig;
|
|
1444
1644
|
constructor(config, hooks, cloudProvider) {
|
|
1445
|
-
|
|
1645
|
+
this.defaultConfig = {
|
|
1446
1646
|
aggressiveness: 0.15,
|
|
1447
1647
|
forcedEfficiency: false,
|
|
1448
1648
|
precisionBias: _IKFirewallCore.CONSTANTS.PRECISION.BIAS_DEFAULT,
|
|
1449
1649
|
balance: _IKFirewallCore.CONSTANTS.TONE.STABLE_VAL,
|
|
1450
1650
|
gatekeeperEnabled: true,
|
|
1451
1651
|
locale: "en",
|
|
1452
|
-
providerMode: "hybrid",
|
|
1652
|
+
providerMode: process.env.IK_FIREWALL_MODE || "hybrid",
|
|
1453
1653
|
runtimeStrategy: "internal",
|
|
1454
|
-
localAuditEndpoint: "http://127.0.0.1:8085/v1/chat/completions",
|
|
1455
|
-
|
|
1654
|
+
localAuditEndpoint: process.env.IK_FIREWALL_LOCAL_ENDPOINT || "http://127.0.0.1:8085/v1/chat/completions",
|
|
1655
|
+
centralReportEndpoint: process.env.IK_FIREWALL_CENTRAL_ENDPOINT || "https://ik-firewall.vercel.app/api/v1/sync",
|
|
1656
|
+
ownerEmail: process.env.IK_FIREWALL_EMAIL,
|
|
1657
|
+
hmacSecret: process.env.IK_FIREWALL_SECRET,
|
|
1658
|
+
fallbackToCloudAudit: process.env.IK_FIREWALL_FALLBACK === "true" || false,
|
|
1456
1659
|
modelConfig: {
|
|
1457
1660
|
modelType: "1b"
|
|
1458
1661
|
},
|
|
1459
1662
|
plugins: []
|
|
1460
1663
|
};
|
|
1461
|
-
this.
|
|
1462
|
-
|
|
1664
|
+
this._hooks = hooks;
|
|
1665
|
+
this.configManager = new ConfigManager({ ...this.defaultConfig, ...config }, hooks);
|
|
1666
|
+
this.gatekeeper = new HeuristicGatekeeper();
|
|
1667
|
+
this.sessionDNA = _IKFirewallCore.CONSTANTS.DNA.MIN;
|
|
1463
1668
|
const activeConfig = this.configManager.getConfig();
|
|
1464
1669
|
this.localProvider = new LocalProvider(activeConfig.localAuditEndpoint);
|
|
1465
1670
|
if (cloudProvider) {
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
const
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1671
|
+
this.cloudProvider = cloudProvider instanceof BaseProvider ? cloudProvider : new OpenAIProvider(cloudProvider);
|
|
1672
|
+
} else if (process.env.OPENAI_API_KEY) {
|
|
1673
|
+
this.cloudProvider = new OpenAIProvider(async (prompt, role) => {
|
|
1674
|
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
1675
|
+
method: "POST",
|
|
1676
|
+
headers: {
|
|
1677
|
+
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
|
|
1678
|
+
"Content-Type": "application/json"
|
|
1679
|
+
},
|
|
1680
|
+
body: JSON.stringify({
|
|
1681
|
+
model: role === "audit_layer" ? "gpt-4o-mini" : "gpt-4o",
|
|
1682
|
+
messages: [{ role: "user", content: prompt }],
|
|
1683
|
+
temperature: 0.1
|
|
1684
|
+
})
|
|
1685
|
+
});
|
|
1686
|
+
if (!response.ok) throw new Error(`OpenAI API Error: ${response.statusText}`);
|
|
1687
|
+
const data = await response.json();
|
|
1688
|
+
return {
|
|
1689
|
+
content: data.choices[0].message.content,
|
|
1690
|
+
usage: data.usage
|
|
1691
|
+
};
|
|
1692
|
+
});
|
|
1482
1693
|
}
|
|
1483
1694
|
this.orchestrator = new Orchestrator(this.configManager);
|
|
1484
|
-
this.usageTracker = new UsageTracker(this.configManager, this.
|
|
1695
|
+
this.usageTracker = new UsageTracker(this.configManager, this._hooks);
|
|
1696
|
+
}
|
|
1697
|
+
get hooks() {
|
|
1698
|
+
return this._hooks;
|
|
1699
|
+
}
|
|
1700
|
+
set hooks(newHooks) {
|
|
1701
|
+
this._hooks = newHooks;
|
|
1702
|
+
this.configManager.setHooks(newHooks);
|
|
1703
|
+
this.usageTracker.hooks = newHooks;
|
|
1485
1704
|
}
|
|
1486
1705
|
static getInstance(config, hooks) {
|
|
1487
1706
|
if (!_IKFirewallCore.instance) {
|
|
@@ -1593,7 +1812,14 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1593
1812
|
async analyze(input, provider, personaName = "professional", locale, instanceId) {
|
|
1594
1813
|
if (instanceId) {
|
|
1595
1814
|
this.configManager.ensureInstanceConfig(instanceId);
|
|
1596
|
-
|
|
1815
|
+
const syncPromise = this.configManager.syncRemoteConfig(instanceId).then(async () => {
|
|
1816
|
+
const pendingUsage = this.configManager._pendingUsage;
|
|
1817
|
+
if (pendingUsage && pendingUsage.length > 0) {
|
|
1818
|
+
await this.usageTracker.flush(pendingUsage);
|
|
1819
|
+
this.configManager._pendingUsage = null;
|
|
1820
|
+
}
|
|
1821
|
+
});
|
|
1822
|
+
await syncPromise;
|
|
1597
1823
|
}
|
|
1598
1824
|
const mergedConfig = this.configManager.getMergedConfig(instanceId);
|
|
1599
1825
|
if (instanceId && mergedConfig?.isVerified === false) {
|
|
@@ -1663,10 +1889,17 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1663
1889
|
throw e;
|
|
1664
1890
|
}
|
|
1665
1891
|
}
|
|
1666
|
-
|
|
1892
|
+
const cqScore = CognitiveEngine.sniffDNA(input);
|
|
1893
|
+
metrics.dm = Math.max(metrics.dm, cqScore / 10);
|
|
1894
|
+
this.applyHardening(input, metrics, activeLocale);
|
|
1667
1895
|
this.hooks?.onAuditComplete?.(metrics);
|
|
1668
1896
|
return metrics;
|
|
1669
1897
|
}
|
|
1898
|
+
applyHardening(input, metrics, locale = "en") {
|
|
1899
|
+
const archetype = metrics.semanticInsights?.archetype || "DYNAMIC";
|
|
1900
|
+
const domain = metrics.semanticInsights?.detectedDomain || "GENERAL";
|
|
1901
|
+
this.setSessionDNA(this.sessionDNA + 5);
|
|
1902
|
+
}
|
|
1670
1903
|
getEmptyMetrics() {
|
|
1671
1904
|
return {
|
|
1672
1905
|
dm: 0,
|
|
@@ -1718,28 +1951,6 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1718
1951
|
inputLength: input.length
|
|
1719
1952
|
};
|
|
1720
1953
|
}
|
|
1721
|
-
sniffDNA(input, metrics, locale = "en") {
|
|
1722
|
-
const archetype = metrics.semanticInsights?.archetype || "DYNAMIC";
|
|
1723
|
-
const domain = metrics.semanticInsights?.detectedDomain || "GENERAL";
|
|
1724
|
-
const meta = Dictionaries.meta[locale] || Dictionaries.meta.en;
|
|
1725
|
-
const patterns = (meta.system_prompt_patterns || "").split(",").map((p) => p.trim()).filter((p) => p.length > 0);
|
|
1726
|
-
const isSystemPrompt = patterns.some((kw) => input.toLowerCase().includes(kw));
|
|
1727
|
-
let dnaShift = 0;
|
|
1728
|
-
if (archetype === "CRYSTAL") {
|
|
1729
|
-
dnaShift += _IKFirewallCore.CONSTANTS.DNA.HARDENING_MODERATE;
|
|
1730
|
-
} else if (archetype === "FLUID") {
|
|
1731
|
-
dnaShift -= _IKFirewallCore.CONSTANTS.DNA.SOFTENING_STEP;
|
|
1732
|
-
} else if (archetype === "NEURAL") {
|
|
1733
|
-
dnaShift -= _IKFirewallCore.CONSTANTS.DNA.SOFTENING_STEP / 2;
|
|
1734
|
-
}
|
|
1735
|
-
if (["LEGAL", "MEDICAL", "FINANCE", "CONSTRUCTION", "ENGINEERING"].includes(domain)) {
|
|
1736
|
-
dnaShift += _IKFirewallCore.CONSTANTS.DNA.HARDENING_DOMAIN;
|
|
1737
|
-
}
|
|
1738
|
-
if (isSystemPrompt) {
|
|
1739
|
-
dnaShift += _IKFirewallCore.CONSTANTS.DNA.HARDENING_MODERATE;
|
|
1740
|
-
}
|
|
1741
|
-
this.setSessionDNA(this.sessionDNA + dnaShift);
|
|
1742
|
-
}
|
|
1743
1954
|
async analyzeAIAssisted(input, provider, personaName = "professional", instanceId, configOverride) {
|
|
1744
1955
|
if (instanceId) {
|
|
1745
1956
|
this.configManager.ensureInstanceConfig(instanceId);
|
|
@@ -1990,11 +2201,13 @@ Any action outside this scope MUST be rejected and flagged as a boundary violati
|
|
|
1990
2201
|
this.hooks?.onStatus?.(`\u{1F6E1}\uFE0F IK_CRYSTALLIZE: Precision domain detected (${domain}). Relaxing noise reduction...`);
|
|
1991
2202
|
archetypeModifier = -0.3;
|
|
1992
2203
|
}
|
|
2204
|
+
const cqScore = CognitiveEngine.sniffDNA(input);
|
|
2205
|
+
const cognitiveThreshold = CognitiveEngine.calculateThreshold(cqScore);
|
|
1993
2206
|
const threshold = Math.min(
|
|
1994
2207
|
_IKFirewallCore.CONSTANTS.AI.THRESHOLD_MAX,
|
|
1995
2208
|
Math.max(
|
|
1996
2209
|
_IKFirewallCore.CONSTANTS.AI.THRESHOLD_MIN,
|
|
1997
|
-
|
|
2210
|
+
cognitiveThreshold + archetypeModifier - tolerance * 0.1
|
|
1998
2211
|
)
|
|
1999
2212
|
);
|
|
2000
2213
|
const lengthRatio = blueprint ? blueprint.length / input.length : 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ik-firewall/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The core IK Firewall engine for semantic-driven AI optimization.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dist",
|
|
18
18
|
"scripts"
|
|
19
19
|
],
|
|
20
|
-
"api_endpoint": "https://ik-firewall
|
|
20
|
+
"api_endpoint": "https://ik-firewall.vercel.app/api/v1",
|
|
21
21
|
"scripts": {
|
|
22
22
|
"prepare": "npm run build",
|
|
23
23
|
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
package/scripts/setup-runtime.js
CHANGED
|
@@ -61,7 +61,9 @@ async function setup() {
|
|
|
61
61
|
"isEnabled": true
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
|
-
|
|
64
|
+
const jsonStr = JSON.stringify(initialRegistry, null, 2);
|
|
65
|
+
const obfuscated = Buffer.from(jsonStr).toString('base64');
|
|
66
|
+
fs.writeFileSync(REGISTRY_FILE, obfuscated, 'utf8');
|
|
65
67
|
console.log(`✨ Trial activated for: ${email}`);
|
|
66
68
|
}
|
|
67
69
|
|