@ik-firewall/core 2.2.0 → 2.3.1
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 +329 -104
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +319 -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,61 @@ var ConfigManager = class {
|
|
|
176
255
|
}
|
|
177
256
|
}
|
|
178
257
|
try {
|
|
179
|
-
const
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
258
|
+
const baseUrl = this.config.centralReportEndpoint || "https://ik-firewall.vercel.app";
|
|
259
|
+
const endpoint = `${baseUrl.replace(/\/$/, "")}/api/v1/sync`;
|
|
260
|
+
const instanceConfig2 = this.config.instanceConfigs?.[instanceId];
|
|
261
|
+
const registrationEmail = instanceConfig2?.ownerEmail || this.config.ownerEmail;
|
|
262
|
+
if ((!instanceConfig2?.licenseKey || instanceConfig2.licenseKey.startsWith("TRIAL-")) && registrationEmail) {
|
|
263
|
+
const success = await this.registerInstance(instanceId, registrationEmail);
|
|
264
|
+
if (success) {
|
|
265
|
+
this.hooks?.onStatus?.("\u2728 IK_SYNC: Zero-Config registration successful. License issued.");
|
|
266
|
+
return;
|
|
267
|
+
} else {
|
|
268
|
+
this.hooks?.onStatus?.("\u26A0\uFE0F IK_SYNC: Auto-registration failed. Continuing with local trial.");
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
this.hooks?.onStatus?.(`\u{1F4E1} IK_SYNC: Heartbeat to ${endpoint}...`);
|
|
272
|
+
const response = await fetch(`${endpoint}?licenseKey=${instanceConfig2?.licenseKey || ""}&instanceId=${instanceId}&version=2.2.0`);
|
|
273
|
+
if (response.ok) {
|
|
274
|
+
const data = await response.json();
|
|
275
|
+
if (this.config.hmacSecret) {
|
|
276
|
+
const verifier = new IKHmac(this.config.hmacSecret);
|
|
277
|
+
if (!verifier.verify(data)) {
|
|
278
|
+
console.error("[IK_SYNC] \u{1F6A8} Signature verification failed! Remote config rejected.");
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
this.setInstanceConfig(instanceId, {
|
|
283
|
+
billingStatus: data.billingStatus,
|
|
284
|
+
isVerified: data.isVerified,
|
|
285
|
+
pricing: data.pricing,
|
|
286
|
+
lastSyncDate: now.toISOString()
|
|
287
|
+
});
|
|
288
|
+
this.hooks?.onStatus?.("\u2705 IK_SYNC: Remote configuration updated and verified.");
|
|
289
|
+
} else {
|
|
290
|
+
throw new Error(`Server responded with ${response.status}`);
|
|
291
|
+
}
|
|
292
|
+
if (!instanceConfig2?.firstUseDate) {
|
|
196
293
|
this.setInstanceConfig(instanceId, { firstUseDate: now.toISOString() });
|
|
197
294
|
}
|
|
198
295
|
} catch (error) {
|
|
199
|
-
console.error(
|
|
296
|
+
console.error(`[IK_CONFIG] Remote sync failed (${error.message}). Falling open (Fail-Open mode).`);
|
|
200
297
|
this.setInstanceConfig(instanceId, {
|
|
201
298
|
isVerified: true,
|
|
202
299
|
lastSyncDate: now.toISOString()
|
|
203
300
|
});
|
|
204
301
|
}
|
|
302
|
+
try {
|
|
303
|
+
const registry = this.registry;
|
|
304
|
+
if (registry.exists(registry.getUsageFilePath())) {
|
|
305
|
+
const aggregatedUsage = registry.loadUsage();
|
|
306
|
+
if (aggregatedUsage.length > 0) {
|
|
307
|
+
this.hooks?.onStatus?.(`\u{1F4CA} IK_SYNC: Found ${aggregatedUsage.length} pending usage reports. Preparation for Daily Flush...`);
|
|
308
|
+
this._pendingUsage = aggregatedUsage;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
} catch (e) {
|
|
312
|
+
}
|
|
205
313
|
}
|
|
206
314
|
getConfig() {
|
|
207
315
|
return { ...this.config };
|
|
@@ -242,6 +350,40 @@ var ConfigManager = class {
|
|
|
242
350
|
}
|
|
243
351
|
this.updateConfig({ plugins });
|
|
244
352
|
}
|
|
353
|
+
async registerInstance(instanceId, email) {
|
|
354
|
+
try {
|
|
355
|
+
const endpoint = (this.config.centralReportEndpoint || "https://ik-firewall.vercel.app/api/v1").replace(/\/sync$/, "") + "/register";
|
|
356
|
+
this.hooks?.onStatus?.(`\u{1F680} IK_REGISTRY: Registering new instance for ${email}...`);
|
|
357
|
+
const response = await fetch(endpoint, {
|
|
358
|
+
method: "POST",
|
|
359
|
+
headers: { "Content-Type": "application/json" },
|
|
360
|
+
body: JSON.stringify({ email, instanceId })
|
|
361
|
+
});
|
|
362
|
+
if (response.ok) {
|
|
363
|
+
const data = await response.json();
|
|
364
|
+
if (this.config.hmacSecret) {
|
|
365
|
+
const verifier = new IKHmac(this.config.hmacSecret);
|
|
366
|
+
if (!verifier.verify(data)) {
|
|
367
|
+
console.error("[IK_REGISTRY] \u{1F6A8} Registration signature mismatch. Data rejected!");
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
this.setInstanceConfig(instanceId, {
|
|
372
|
+
licenseKey: data.licenseKey,
|
|
373
|
+
billingStatus: data.status.toLowerCase(),
|
|
374
|
+
isVerified: true,
|
|
375
|
+
firstUseDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
376
|
+
pricing: data.pricing
|
|
377
|
+
});
|
|
378
|
+
this.hooks?.onStatus?.("\u2728 IK_REGISTRY: Instance registered successfully and license issued.");
|
|
379
|
+
return true;
|
|
380
|
+
}
|
|
381
|
+
return false;
|
|
382
|
+
} catch (error) {
|
|
383
|
+
console.error("[IK_REGISTRY] Registration failed:", error);
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
245
387
|
ensureInstanceConfig(instanceId) {
|
|
246
388
|
const all = this.registry.load();
|
|
247
389
|
if (!all[instanceId]) {
|
|
@@ -249,7 +391,9 @@ var ConfigManager = class {
|
|
|
249
391
|
balance: this.config.balance || 0.5,
|
|
250
392
|
aggressiveness: this.config.aggressiveness || 0.5,
|
|
251
393
|
isEnabled: true,
|
|
252
|
-
contextMode: "FIRST_MESSAGE"
|
|
394
|
+
contextMode: "FIRST_MESSAGE",
|
|
395
|
+
ownerEmail: this.config.ownerEmail
|
|
396
|
+
// Inherit from global if not specific
|
|
253
397
|
});
|
|
254
398
|
this.loadFromRegistry();
|
|
255
399
|
}
|
|
@@ -1328,12 +1472,6 @@ var UsageTracker = class {
|
|
|
1328
1472
|
// Immediate reporting for Edge/Stateless environments
|
|
1329
1473
|
hooks;
|
|
1330
1474
|
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
1475
|
constructor(config, hooks) {
|
|
1338
1476
|
this.config = config;
|
|
1339
1477
|
this.hooks = hooks;
|
|
@@ -1366,42 +1504,72 @@ var UsageTracker = class {
|
|
|
1366
1504
|
};
|
|
1367
1505
|
this.buffer.push(data);
|
|
1368
1506
|
this.hooks?.onUsageReported?.(data);
|
|
1369
|
-
|
|
1370
|
-
|
|
1507
|
+
await this.persistToLocalBuffer(data);
|
|
1508
|
+
}
|
|
1509
|
+
/**
|
|
1510
|
+
* Appends usage data to the local .ik-adapter/usage.json file
|
|
1511
|
+
*/
|
|
1512
|
+
async persistToLocalBuffer(data) {
|
|
1513
|
+
try {
|
|
1514
|
+
const registry = this.config.getRegistry();
|
|
1515
|
+
const usageFile = registry.getUsageFilePath();
|
|
1516
|
+
let existingUsage = [];
|
|
1517
|
+
if (registry.exists(usageFile)) {
|
|
1518
|
+
existingUsage = registry.loadUsage();
|
|
1519
|
+
}
|
|
1520
|
+
existingUsage.push(data);
|
|
1521
|
+
registry.saveUsage(existingUsage);
|
|
1522
|
+
} catch (e) {
|
|
1523
|
+
console.error("[IK_TRACKER] Failed to persist usage to local buffer:", e);
|
|
1371
1524
|
}
|
|
1372
1525
|
}
|
|
1373
1526
|
/**
|
|
1374
1527
|
* Send buffered usage data to the central IK billing service
|
|
1375
1528
|
*/
|
|
1376
|
-
async flush() {
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
}
|
|
1529
|
+
async flush(aggregatedData) {
|
|
1530
|
+
const usageToFlush = aggregatedData || this.buffer;
|
|
1531
|
+
if (usageToFlush.length === 0) return;
|
|
1532
|
+
const baseUrl = this.config.get("centralReportEndpoint") || "https://ik-firewall.vercel.app";
|
|
1533
|
+
const endpoint = `${baseUrl.replace(/\/$/, "")}/api/v1/report`;
|
|
1534
|
+
const hmacSecret = this.config.get("hmacSecret");
|
|
1383
1535
|
try {
|
|
1384
|
-
|
|
1385
|
-
|
|
1536
|
+
this.hooks?.onStatus?.(`\u{1F4E4} IK_TRACKER: Flushing ${usageToFlush.length} interactions to ${endpoint}...`);
|
|
1537
|
+
const reportsByInstance = {};
|
|
1538
|
+
for (const report of usageToFlush) {
|
|
1539
|
+
if (!reportsByInstance[report.instanceId]) reportsByInstance[report.instanceId] = [];
|
|
1540
|
+
reportsByInstance[report.instanceId].push(report);
|
|
1541
|
+
}
|
|
1542
|
+
for (const [instanceId, reports] of Object.entries(reportsByInstance)) {
|
|
1543
|
+
const instanceConfig = this.config.getConfig().instanceConfigs?.[instanceId];
|
|
1544
|
+
const payload = {
|
|
1545
|
+
licenseKey: instanceConfig?.licenseKey || "",
|
|
1546
|
+
instanceId,
|
|
1547
|
+
reports: reports.map((r) => ({
|
|
1548
|
+
modelName: r.model_used,
|
|
1549
|
+
tokensIn: r.input_tokens,
|
|
1550
|
+
tokensOut: r.output_tokens,
|
|
1551
|
+
tokensSaved: r.tokens_saved,
|
|
1552
|
+
date: r.timestamp
|
|
1553
|
+
}))
|
|
1554
|
+
};
|
|
1555
|
+
if (hmacSecret) {
|
|
1556
|
+
const jsonStr = JSON.stringify(payload);
|
|
1557
|
+
const crypto2 = await import("crypto");
|
|
1558
|
+
payload.signature = crypto2.createHmac("sha256", hmacSecret).update(jsonStr).digest("hex");
|
|
1559
|
+
}
|
|
1560
|
+
const response = await fetch(endpoint, {
|
|
1386
1561
|
method: "POST",
|
|
1387
1562
|
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
|
-
})
|
|
1563
|
+
body: JSON.stringify(payload)
|
|
1402
1564
|
});
|
|
1565
|
+
if (!response.ok) {
|
|
1566
|
+
console.error(`[IK_TRACKER] Failed to send aggregate for ${instanceId}: ${response.statusText}`);
|
|
1567
|
+
}
|
|
1403
1568
|
}
|
|
1404
1569
|
this.buffer = [];
|
|
1570
|
+
if (aggregatedData) {
|
|
1571
|
+
this.config.getRegistry().clearUsage();
|
|
1572
|
+
}
|
|
1405
1573
|
} catch (error) {
|
|
1406
1574
|
console.error("[IK_TRACKER] Failed to flush usage data:", error);
|
|
1407
1575
|
}
|
|
@@ -1411,6 +1579,49 @@ var UsageTracker = class {
|
|
|
1411
1579
|
}
|
|
1412
1580
|
};
|
|
1413
1581
|
|
|
1582
|
+
// src/CognitiveEngine.ts
|
|
1583
|
+
var CognitiveEngine = class {
|
|
1584
|
+
/**
|
|
1585
|
+
* Sniff Cognitive DNA (CQ Score: 0-100)
|
|
1586
|
+
* Higher score = higher quality, human-like, structured content.
|
|
1587
|
+
*/
|
|
1588
|
+
static sniffDNA(input) {
|
|
1589
|
+
if (!input || input.trim().length === 0) return 0;
|
|
1590
|
+
const length = input.length;
|
|
1591
|
+
const words = input.split(/\s+/).filter((w) => w.length > 0);
|
|
1592
|
+
const wordCount = words.length;
|
|
1593
|
+
const sentences = input.split(/[.!?]+/).filter((s) => s.trim().length > 0);
|
|
1594
|
+
const avgSentenceLength = sentences.length > 0 ? wordCount / sentences.length : 0;
|
|
1595
|
+
const sentenceVariety = sentences.length > 1 ? 10 : 0;
|
|
1596
|
+
const uniqueWords = new Set(words.map((w) => w.toLowerCase())).size;
|
|
1597
|
+
const lexicalBreadth = wordCount > 0 ? uniqueWords / wordCount * 40 : 0;
|
|
1598
|
+
const markers = (input.match(/[,;:"'()\[\]]/g) || []).length;
|
|
1599
|
+
const structuralHealth = Math.min(markers / wordCount * 100, 20);
|
|
1600
|
+
const repetitivePenalty = this.calculateRepetitivePenalty(input);
|
|
1601
|
+
let score = lexicalBreadth + structuralHealth + sentenceVariety + (avgSentenceLength > 5 ? 20 : 0);
|
|
1602
|
+
score -= repetitivePenalty;
|
|
1603
|
+
return Math.max(0, Math.min(100, score));
|
|
1604
|
+
}
|
|
1605
|
+
/**
|
|
1606
|
+
* Calculate Crystallization Threshold
|
|
1607
|
+
* Logic:
|
|
1608
|
+
* Low CQ (Noise) -> Aggressive optimization (Lower threshold, e.g. 0.6)
|
|
1609
|
+
* High CQ (Quality) -> Conservative optimization (Higher threshold, e.g. 0.9)
|
|
1610
|
+
*/
|
|
1611
|
+
static calculateThreshold(cqScore) {
|
|
1612
|
+
if (cqScore < 30) return 0.65;
|
|
1613
|
+
if (cqScore < 60) return 0.78;
|
|
1614
|
+
if (cqScore < 85) return 0.88;
|
|
1615
|
+
return 0.95;
|
|
1616
|
+
}
|
|
1617
|
+
static calculateRepetitivePenalty(input) {
|
|
1618
|
+
const chunks = input.match(/.{1,10}/g) || [];
|
|
1619
|
+
const uniqueChunks = new Set(chunks).size;
|
|
1620
|
+
const ratio = chunks.length > 10 ? uniqueChunks / chunks.length : 1;
|
|
1621
|
+
return ratio < 0.5 ? (1 - ratio) * 50 : 0;
|
|
1622
|
+
}
|
|
1623
|
+
};
|
|
1624
|
+
|
|
1414
1625
|
// src/core.ts
|
|
1415
1626
|
var IKFirewallCore = class _IKFirewallCore {
|
|
1416
1627
|
static instance;
|
|
@@ -1465,55 +1676,75 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1465
1676
|
FLUID_THRESHOLD: 4
|
|
1466
1677
|
}
|
|
1467
1678
|
};
|
|
1468
|
-
gatekeeper
|
|
1679
|
+
gatekeeper;
|
|
1469
1680
|
configManager;
|
|
1470
1681
|
sessionDNA = 0;
|
|
1471
|
-
hooks;
|
|
1472
1682
|
cloudProvider;
|
|
1473
1683
|
localProvider;
|
|
1474
1684
|
orchestrator;
|
|
1475
1685
|
usageTracker;
|
|
1686
|
+
_hooks;
|
|
1687
|
+
defaultConfig;
|
|
1476
1688
|
constructor(config, hooks, cloudProvider) {
|
|
1477
|
-
|
|
1689
|
+
this.defaultConfig = {
|
|
1478
1690
|
aggressiveness: 0.15,
|
|
1479
1691
|
forcedEfficiency: false,
|
|
1480
1692
|
precisionBias: _IKFirewallCore.CONSTANTS.PRECISION.BIAS_DEFAULT,
|
|
1481
1693
|
balance: _IKFirewallCore.CONSTANTS.TONE.STABLE_VAL,
|
|
1482
1694
|
gatekeeperEnabled: true,
|
|
1483
1695
|
locale: "en",
|
|
1484
|
-
providerMode: "hybrid",
|
|
1696
|
+
providerMode: process.env.IK_FIREWALL_MODE || "hybrid",
|
|
1485
1697
|
runtimeStrategy: "internal",
|
|
1486
|
-
localAuditEndpoint: "http://127.0.0.1:8085/v1/chat/completions",
|
|
1487
|
-
|
|
1698
|
+
localAuditEndpoint: process.env.IK_FIREWALL_LOCAL_ENDPOINT || "http://127.0.0.1:8085/v1/chat/completions",
|
|
1699
|
+
centralReportEndpoint: (process.env.IK_FIREWALL_CENTRAL_ENDPOINT || "https://ik-firewall.vercel.app").replace(/\/$/, ""),
|
|
1700
|
+
ownerEmail: process.env.IK_FIREWALL_EMAIL,
|
|
1701
|
+
hmacSecret: process.env.IK_FIREWALL_SECRET,
|
|
1702
|
+
fallbackToCloudAudit: process.env.IK_FIREWALL_FALLBACK === "true" || false,
|
|
1488
1703
|
modelConfig: {
|
|
1489
1704
|
modelType: "1b"
|
|
1490
1705
|
},
|
|
1491
1706
|
plugins: []
|
|
1492
1707
|
};
|
|
1493
|
-
this.
|
|
1494
|
-
|
|
1708
|
+
this._hooks = hooks;
|
|
1709
|
+
this.configManager = new ConfigManager({ ...this.defaultConfig, ...config }, hooks);
|
|
1710
|
+
this.gatekeeper = new HeuristicGatekeeper();
|
|
1711
|
+
this.sessionDNA = _IKFirewallCore.CONSTANTS.DNA.MIN;
|
|
1495
1712
|
const activeConfig = this.configManager.getConfig();
|
|
1496
1713
|
this.localProvider = new LocalProvider(activeConfig.localAuditEndpoint);
|
|
1497
1714
|
if (cloudProvider) {
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
const
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1715
|
+
this.cloudProvider = cloudProvider instanceof BaseProvider ? cloudProvider : new OpenAIProvider(cloudProvider);
|
|
1716
|
+
} else if (process.env.OPENAI_API_KEY) {
|
|
1717
|
+
this.cloudProvider = new OpenAIProvider(async (prompt, role) => {
|
|
1718
|
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
1719
|
+
method: "POST",
|
|
1720
|
+
headers: {
|
|
1721
|
+
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
|
|
1722
|
+
"Content-Type": "application/json"
|
|
1723
|
+
},
|
|
1724
|
+
body: JSON.stringify({
|
|
1725
|
+
model: role === "audit_layer" ? "gpt-4o-mini" : "gpt-4o",
|
|
1726
|
+
messages: [{ role: "user", content: prompt }],
|
|
1727
|
+
temperature: 0.1
|
|
1728
|
+
})
|
|
1729
|
+
});
|
|
1730
|
+
if (!response.ok) throw new Error(`OpenAI API Error: ${response.statusText}`);
|
|
1731
|
+
const data = await response.json();
|
|
1732
|
+
return {
|
|
1733
|
+
content: data.choices[0].message.content,
|
|
1734
|
+
usage: data.usage
|
|
1735
|
+
};
|
|
1736
|
+
});
|
|
1514
1737
|
}
|
|
1515
1738
|
this.orchestrator = new Orchestrator(this.configManager);
|
|
1516
|
-
this.usageTracker = new UsageTracker(this.configManager, this.
|
|
1739
|
+
this.usageTracker = new UsageTracker(this.configManager, this._hooks);
|
|
1740
|
+
}
|
|
1741
|
+
get hooks() {
|
|
1742
|
+
return this._hooks;
|
|
1743
|
+
}
|
|
1744
|
+
set hooks(newHooks) {
|
|
1745
|
+
this._hooks = newHooks;
|
|
1746
|
+
this.configManager.setHooks(newHooks);
|
|
1747
|
+
this.usageTracker.hooks = newHooks;
|
|
1517
1748
|
}
|
|
1518
1749
|
static getInstance(config, hooks) {
|
|
1519
1750
|
if (!_IKFirewallCore.instance) {
|
|
@@ -1625,7 +1856,14 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1625
1856
|
async analyze(input, provider, personaName = "professional", locale, instanceId) {
|
|
1626
1857
|
if (instanceId) {
|
|
1627
1858
|
this.configManager.ensureInstanceConfig(instanceId);
|
|
1628
|
-
|
|
1859
|
+
const syncPromise = this.configManager.syncRemoteConfig(instanceId).then(async () => {
|
|
1860
|
+
const pendingUsage = this.configManager._pendingUsage;
|
|
1861
|
+
if (pendingUsage && pendingUsage.length > 0) {
|
|
1862
|
+
await this.usageTracker.flush(pendingUsage);
|
|
1863
|
+
this.configManager._pendingUsage = null;
|
|
1864
|
+
}
|
|
1865
|
+
});
|
|
1866
|
+
await syncPromise;
|
|
1629
1867
|
}
|
|
1630
1868
|
const mergedConfig = this.configManager.getMergedConfig(instanceId);
|
|
1631
1869
|
if (instanceId && mergedConfig?.isVerified === false) {
|
|
@@ -1695,10 +1933,17 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1695
1933
|
throw e;
|
|
1696
1934
|
}
|
|
1697
1935
|
}
|
|
1698
|
-
|
|
1936
|
+
const cqScore = CognitiveEngine.sniffDNA(input);
|
|
1937
|
+
metrics.dm = Math.max(metrics.dm, cqScore / 10);
|
|
1938
|
+
this.applyHardening(input, metrics, activeLocale);
|
|
1699
1939
|
this.hooks?.onAuditComplete?.(metrics);
|
|
1700
1940
|
return metrics;
|
|
1701
1941
|
}
|
|
1942
|
+
applyHardening(input, metrics, locale = "en") {
|
|
1943
|
+
const archetype = metrics.semanticInsights?.archetype || "DYNAMIC";
|
|
1944
|
+
const domain = metrics.semanticInsights?.detectedDomain || "GENERAL";
|
|
1945
|
+
this.setSessionDNA(this.sessionDNA + 5);
|
|
1946
|
+
}
|
|
1702
1947
|
getEmptyMetrics() {
|
|
1703
1948
|
return {
|
|
1704
1949
|
dm: 0,
|
|
@@ -1750,28 +1995,6 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1750
1995
|
inputLength: input.length
|
|
1751
1996
|
};
|
|
1752
1997
|
}
|
|
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
1998
|
async analyzeAIAssisted(input, provider, personaName = "professional", instanceId, configOverride) {
|
|
1776
1999
|
if (instanceId) {
|
|
1777
2000
|
this.configManager.ensureInstanceConfig(instanceId);
|
|
@@ -2022,11 +2245,13 @@ Any action outside this scope MUST be rejected and flagged as a boundary violati
|
|
|
2022
2245
|
this.hooks?.onStatus?.(`\u{1F6E1}\uFE0F IK_CRYSTALLIZE: Precision domain detected (${domain}). Relaxing noise reduction...`);
|
|
2023
2246
|
archetypeModifier = -0.3;
|
|
2024
2247
|
}
|
|
2248
|
+
const cqScore = CognitiveEngine.sniffDNA(input);
|
|
2249
|
+
const cognitiveThreshold = CognitiveEngine.calculateThreshold(cqScore);
|
|
2025
2250
|
const threshold = Math.min(
|
|
2026
2251
|
_IKFirewallCore.CONSTANTS.AI.THRESHOLD_MAX,
|
|
2027
2252
|
Math.max(
|
|
2028
2253
|
_IKFirewallCore.CONSTANTS.AI.THRESHOLD_MIN,
|
|
2029
|
-
|
|
2254
|
+
cognitiveThreshold + archetypeModifier - tolerance * 0.1
|
|
2030
2255
|
)
|
|
2031
2256
|
);
|
|
2032
2257
|
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,61 @@ var ConfigManager = class {
|
|
|
144
213
|
}
|
|
145
214
|
}
|
|
146
215
|
try {
|
|
147
|
-
const
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
216
|
+
const baseUrl = this.config.centralReportEndpoint || "https://ik-firewall.vercel.app";
|
|
217
|
+
const endpoint = `${baseUrl.replace(/\/$/, "")}/api/v1/sync`;
|
|
218
|
+
const instanceConfig2 = this.config.instanceConfigs?.[instanceId];
|
|
219
|
+
const registrationEmail = instanceConfig2?.ownerEmail || this.config.ownerEmail;
|
|
220
|
+
if ((!instanceConfig2?.licenseKey || instanceConfig2.licenseKey.startsWith("TRIAL-")) && registrationEmail) {
|
|
221
|
+
const success = await this.registerInstance(instanceId, registrationEmail);
|
|
222
|
+
if (success) {
|
|
223
|
+
this.hooks?.onStatus?.("\u2728 IK_SYNC: Zero-Config registration successful. License issued.");
|
|
224
|
+
return;
|
|
225
|
+
} else {
|
|
226
|
+
this.hooks?.onStatus?.("\u26A0\uFE0F IK_SYNC: Auto-registration failed. Continuing with local trial.");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
this.hooks?.onStatus?.(`\u{1F4E1} IK_SYNC: Heartbeat to ${endpoint}...`);
|
|
230
|
+
const response = await fetch(`${endpoint}?licenseKey=${instanceConfig2?.licenseKey || ""}&instanceId=${instanceId}&version=2.2.0`);
|
|
231
|
+
if (response.ok) {
|
|
232
|
+
const data = await response.json();
|
|
233
|
+
if (this.config.hmacSecret) {
|
|
234
|
+
const verifier = new IKHmac(this.config.hmacSecret);
|
|
235
|
+
if (!verifier.verify(data)) {
|
|
236
|
+
console.error("[IK_SYNC] \u{1F6A8} Signature verification failed! Remote config rejected.");
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
this.setInstanceConfig(instanceId, {
|
|
241
|
+
billingStatus: data.billingStatus,
|
|
242
|
+
isVerified: data.isVerified,
|
|
243
|
+
pricing: data.pricing,
|
|
244
|
+
lastSyncDate: now.toISOString()
|
|
245
|
+
});
|
|
246
|
+
this.hooks?.onStatus?.("\u2705 IK_SYNC: Remote configuration updated and verified.");
|
|
247
|
+
} else {
|
|
248
|
+
throw new Error(`Server responded with ${response.status}`);
|
|
249
|
+
}
|
|
250
|
+
if (!instanceConfig2?.firstUseDate) {
|
|
164
251
|
this.setInstanceConfig(instanceId, { firstUseDate: now.toISOString() });
|
|
165
252
|
}
|
|
166
253
|
} catch (error) {
|
|
167
|
-
console.error(
|
|
254
|
+
console.error(`[IK_CONFIG] Remote sync failed (${error.message}). Falling open (Fail-Open mode).`);
|
|
168
255
|
this.setInstanceConfig(instanceId, {
|
|
169
256
|
isVerified: true,
|
|
170
257
|
lastSyncDate: now.toISOString()
|
|
171
258
|
});
|
|
172
259
|
}
|
|
260
|
+
try {
|
|
261
|
+
const registry = this.registry;
|
|
262
|
+
if (registry.exists(registry.getUsageFilePath())) {
|
|
263
|
+
const aggregatedUsage = registry.loadUsage();
|
|
264
|
+
if (aggregatedUsage.length > 0) {
|
|
265
|
+
this.hooks?.onStatus?.(`\u{1F4CA} IK_SYNC: Found ${aggregatedUsage.length} pending usage reports. Preparation for Daily Flush...`);
|
|
266
|
+
this._pendingUsage = aggregatedUsage;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
} catch (e) {
|
|
270
|
+
}
|
|
173
271
|
}
|
|
174
272
|
getConfig() {
|
|
175
273
|
return { ...this.config };
|
|
@@ -210,6 +308,40 @@ var ConfigManager = class {
|
|
|
210
308
|
}
|
|
211
309
|
this.updateConfig({ plugins });
|
|
212
310
|
}
|
|
311
|
+
async registerInstance(instanceId, email) {
|
|
312
|
+
try {
|
|
313
|
+
const endpoint = (this.config.centralReportEndpoint || "https://ik-firewall.vercel.app/api/v1").replace(/\/sync$/, "") + "/register";
|
|
314
|
+
this.hooks?.onStatus?.(`\u{1F680} IK_REGISTRY: Registering new instance for ${email}...`);
|
|
315
|
+
const response = await fetch(endpoint, {
|
|
316
|
+
method: "POST",
|
|
317
|
+
headers: { "Content-Type": "application/json" },
|
|
318
|
+
body: JSON.stringify({ email, instanceId })
|
|
319
|
+
});
|
|
320
|
+
if (response.ok) {
|
|
321
|
+
const data = await response.json();
|
|
322
|
+
if (this.config.hmacSecret) {
|
|
323
|
+
const verifier = new IKHmac(this.config.hmacSecret);
|
|
324
|
+
if (!verifier.verify(data)) {
|
|
325
|
+
console.error("[IK_REGISTRY] \u{1F6A8} Registration signature mismatch. Data rejected!");
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
this.setInstanceConfig(instanceId, {
|
|
330
|
+
licenseKey: data.licenseKey,
|
|
331
|
+
billingStatus: data.status.toLowerCase(),
|
|
332
|
+
isVerified: true,
|
|
333
|
+
firstUseDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
334
|
+
pricing: data.pricing
|
|
335
|
+
});
|
|
336
|
+
this.hooks?.onStatus?.("\u2728 IK_REGISTRY: Instance registered successfully and license issued.");
|
|
337
|
+
return true;
|
|
338
|
+
}
|
|
339
|
+
return false;
|
|
340
|
+
} catch (error) {
|
|
341
|
+
console.error("[IK_REGISTRY] Registration failed:", error);
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
213
345
|
ensureInstanceConfig(instanceId) {
|
|
214
346
|
const all = this.registry.load();
|
|
215
347
|
if (!all[instanceId]) {
|
|
@@ -217,7 +349,9 @@ var ConfigManager = class {
|
|
|
217
349
|
balance: this.config.balance || 0.5,
|
|
218
350
|
aggressiveness: this.config.aggressiveness || 0.5,
|
|
219
351
|
isEnabled: true,
|
|
220
|
-
contextMode: "FIRST_MESSAGE"
|
|
352
|
+
contextMode: "FIRST_MESSAGE",
|
|
353
|
+
ownerEmail: this.config.ownerEmail
|
|
354
|
+
// Inherit from global if not specific
|
|
221
355
|
});
|
|
222
356
|
this.loadFromRegistry();
|
|
223
357
|
}
|
|
@@ -1296,12 +1430,6 @@ var UsageTracker = class {
|
|
|
1296
1430
|
// Immediate reporting for Edge/Stateless environments
|
|
1297
1431
|
hooks;
|
|
1298
1432
|
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
1433
|
constructor(config, hooks) {
|
|
1306
1434
|
this.config = config;
|
|
1307
1435
|
this.hooks = hooks;
|
|
@@ -1334,42 +1462,72 @@ var UsageTracker = class {
|
|
|
1334
1462
|
};
|
|
1335
1463
|
this.buffer.push(data);
|
|
1336
1464
|
this.hooks?.onUsageReported?.(data);
|
|
1337
|
-
|
|
1338
|
-
|
|
1465
|
+
await this.persistToLocalBuffer(data);
|
|
1466
|
+
}
|
|
1467
|
+
/**
|
|
1468
|
+
* Appends usage data to the local .ik-adapter/usage.json file
|
|
1469
|
+
*/
|
|
1470
|
+
async persistToLocalBuffer(data) {
|
|
1471
|
+
try {
|
|
1472
|
+
const registry = this.config.getRegistry();
|
|
1473
|
+
const usageFile = registry.getUsageFilePath();
|
|
1474
|
+
let existingUsage = [];
|
|
1475
|
+
if (registry.exists(usageFile)) {
|
|
1476
|
+
existingUsage = registry.loadUsage();
|
|
1477
|
+
}
|
|
1478
|
+
existingUsage.push(data);
|
|
1479
|
+
registry.saveUsage(existingUsage);
|
|
1480
|
+
} catch (e) {
|
|
1481
|
+
console.error("[IK_TRACKER] Failed to persist usage to local buffer:", e);
|
|
1339
1482
|
}
|
|
1340
1483
|
}
|
|
1341
1484
|
/**
|
|
1342
1485
|
* Send buffered usage data to the central IK billing service
|
|
1343
1486
|
*/
|
|
1344
|
-
async flush() {
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
}
|
|
1487
|
+
async flush(aggregatedData) {
|
|
1488
|
+
const usageToFlush = aggregatedData || this.buffer;
|
|
1489
|
+
if (usageToFlush.length === 0) return;
|
|
1490
|
+
const baseUrl = this.config.get("centralReportEndpoint") || "https://ik-firewall.vercel.app";
|
|
1491
|
+
const endpoint = `${baseUrl.replace(/\/$/, "")}/api/v1/report`;
|
|
1492
|
+
const hmacSecret = this.config.get("hmacSecret");
|
|
1351
1493
|
try {
|
|
1352
|
-
|
|
1353
|
-
|
|
1494
|
+
this.hooks?.onStatus?.(`\u{1F4E4} IK_TRACKER: Flushing ${usageToFlush.length} interactions to ${endpoint}...`);
|
|
1495
|
+
const reportsByInstance = {};
|
|
1496
|
+
for (const report of usageToFlush) {
|
|
1497
|
+
if (!reportsByInstance[report.instanceId]) reportsByInstance[report.instanceId] = [];
|
|
1498
|
+
reportsByInstance[report.instanceId].push(report);
|
|
1499
|
+
}
|
|
1500
|
+
for (const [instanceId, reports] of Object.entries(reportsByInstance)) {
|
|
1501
|
+
const instanceConfig = this.config.getConfig().instanceConfigs?.[instanceId];
|
|
1502
|
+
const payload = {
|
|
1503
|
+
licenseKey: instanceConfig?.licenseKey || "",
|
|
1504
|
+
instanceId,
|
|
1505
|
+
reports: reports.map((r) => ({
|
|
1506
|
+
modelName: r.model_used,
|
|
1507
|
+
tokensIn: r.input_tokens,
|
|
1508
|
+
tokensOut: r.output_tokens,
|
|
1509
|
+
tokensSaved: r.tokens_saved,
|
|
1510
|
+
date: r.timestamp
|
|
1511
|
+
}))
|
|
1512
|
+
};
|
|
1513
|
+
if (hmacSecret) {
|
|
1514
|
+
const jsonStr = JSON.stringify(payload);
|
|
1515
|
+
const crypto2 = await import("crypto");
|
|
1516
|
+
payload.signature = crypto2.createHmac("sha256", hmacSecret).update(jsonStr).digest("hex");
|
|
1517
|
+
}
|
|
1518
|
+
const response = await fetch(endpoint, {
|
|
1354
1519
|
method: "POST",
|
|
1355
1520
|
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
|
-
})
|
|
1521
|
+
body: JSON.stringify(payload)
|
|
1370
1522
|
});
|
|
1523
|
+
if (!response.ok) {
|
|
1524
|
+
console.error(`[IK_TRACKER] Failed to send aggregate for ${instanceId}: ${response.statusText}`);
|
|
1525
|
+
}
|
|
1371
1526
|
}
|
|
1372
1527
|
this.buffer = [];
|
|
1528
|
+
if (aggregatedData) {
|
|
1529
|
+
this.config.getRegistry().clearUsage();
|
|
1530
|
+
}
|
|
1373
1531
|
} catch (error) {
|
|
1374
1532
|
console.error("[IK_TRACKER] Failed to flush usage data:", error);
|
|
1375
1533
|
}
|
|
@@ -1379,6 +1537,49 @@ var UsageTracker = class {
|
|
|
1379
1537
|
}
|
|
1380
1538
|
};
|
|
1381
1539
|
|
|
1540
|
+
// src/CognitiveEngine.ts
|
|
1541
|
+
var CognitiveEngine = class {
|
|
1542
|
+
/**
|
|
1543
|
+
* Sniff Cognitive DNA (CQ Score: 0-100)
|
|
1544
|
+
* Higher score = higher quality, human-like, structured content.
|
|
1545
|
+
*/
|
|
1546
|
+
static sniffDNA(input) {
|
|
1547
|
+
if (!input || input.trim().length === 0) return 0;
|
|
1548
|
+
const length = input.length;
|
|
1549
|
+
const words = input.split(/\s+/).filter((w) => w.length > 0);
|
|
1550
|
+
const wordCount = words.length;
|
|
1551
|
+
const sentences = input.split(/[.!?]+/).filter((s) => s.trim().length > 0);
|
|
1552
|
+
const avgSentenceLength = sentences.length > 0 ? wordCount / sentences.length : 0;
|
|
1553
|
+
const sentenceVariety = sentences.length > 1 ? 10 : 0;
|
|
1554
|
+
const uniqueWords = new Set(words.map((w) => w.toLowerCase())).size;
|
|
1555
|
+
const lexicalBreadth = wordCount > 0 ? uniqueWords / wordCount * 40 : 0;
|
|
1556
|
+
const markers = (input.match(/[,;:"'()\[\]]/g) || []).length;
|
|
1557
|
+
const structuralHealth = Math.min(markers / wordCount * 100, 20);
|
|
1558
|
+
const repetitivePenalty = this.calculateRepetitivePenalty(input);
|
|
1559
|
+
let score = lexicalBreadth + structuralHealth + sentenceVariety + (avgSentenceLength > 5 ? 20 : 0);
|
|
1560
|
+
score -= repetitivePenalty;
|
|
1561
|
+
return Math.max(0, Math.min(100, score));
|
|
1562
|
+
}
|
|
1563
|
+
/**
|
|
1564
|
+
* Calculate Crystallization Threshold
|
|
1565
|
+
* Logic:
|
|
1566
|
+
* Low CQ (Noise) -> Aggressive optimization (Lower threshold, e.g. 0.6)
|
|
1567
|
+
* High CQ (Quality) -> Conservative optimization (Higher threshold, e.g. 0.9)
|
|
1568
|
+
*/
|
|
1569
|
+
static calculateThreshold(cqScore) {
|
|
1570
|
+
if (cqScore < 30) return 0.65;
|
|
1571
|
+
if (cqScore < 60) return 0.78;
|
|
1572
|
+
if (cqScore < 85) return 0.88;
|
|
1573
|
+
return 0.95;
|
|
1574
|
+
}
|
|
1575
|
+
static calculateRepetitivePenalty(input) {
|
|
1576
|
+
const chunks = input.match(/.{1,10}/g) || [];
|
|
1577
|
+
const uniqueChunks = new Set(chunks).size;
|
|
1578
|
+
const ratio = chunks.length > 10 ? uniqueChunks / chunks.length : 1;
|
|
1579
|
+
return ratio < 0.5 ? (1 - ratio) * 50 : 0;
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
|
|
1382
1583
|
// src/core.ts
|
|
1383
1584
|
var IKFirewallCore = class _IKFirewallCore {
|
|
1384
1585
|
static instance;
|
|
@@ -1433,55 +1634,75 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1433
1634
|
FLUID_THRESHOLD: 4
|
|
1434
1635
|
}
|
|
1435
1636
|
};
|
|
1436
|
-
gatekeeper
|
|
1637
|
+
gatekeeper;
|
|
1437
1638
|
configManager;
|
|
1438
1639
|
sessionDNA = 0;
|
|
1439
|
-
hooks;
|
|
1440
1640
|
cloudProvider;
|
|
1441
1641
|
localProvider;
|
|
1442
1642
|
orchestrator;
|
|
1443
1643
|
usageTracker;
|
|
1644
|
+
_hooks;
|
|
1645
|
+
defaultConfig;
|
|
1444
1646
|
constructor(config, hooks, cloudProvider) {
|
|
1445
|
-
|
|
1647
|
+
this.defaultConfig = {
|
|
1446
1648
|
aggressiveness: 0.15,
|
|
1447
1649
|
forcedEfficiency: false,
|
|
1448
1650
|
precisionBias: _IKFirewallCore.CONSTANTS.PRECISION.BIAS_DEFAULT,
|
|
1449
1651
|
balance: _IKFirewallCore.CONSTANTS.TONE.STABLE_VAL,
|
|
1450
1652
|
gatekeeperEnabled: true,
|
|
1451
1653
|
locale: "en",
|
|
1452
|
-
providerMode: "hybrid",
|
|
1654
|
+
providerMode: process.env.IK_FIREWALL_MODE || "hybrid",
|
|
1453
1655
|
runtimeStrategy: "internal",
|
|
1454
|
-
localAuditEndpoint: "http://127.0.0.1:8085/v1/chat/completions",
|
|
1455
|
-
|
|
1656
|
+
localAuditEndpoint: process.env.IK_FIREWALL_LOCAL_ENDPOINT || "http://127.0.0.1:8085/v1/chat/completions",
|
|
1657
|
+
centralReportEndpoint: (process.env.IK_FIREWALL_CENTRAL_ENDPOINT || "https://ik-firewall.vercel.app").replace(/\/$/, ""),
|
|
1658
|
+
ownerEmail: process.env.IK_FIREWALL_EMAIL,
|
|
1659
|
+
hmacSecret: process.env.IK_FIREWALL_SECRET,
|
|
1660
|
+
fallbackToCloudAudit: process.env.IK_FIREWALL_FALLBACK === "true" || false,
|
|
1456
1661
|
modelConfig: {
|
|
1457
1662
|
modelType: "1b"
|
|
1458
1663
|
},
|
|
1459
1664
|
plugins: []
|
|
1460
1665
|
};
|
|
1461
|
-
this.
|
|
1462
|
-
|
|
1666
|
+
this._hooks = hooks;
|
|
1667
|
+
this.configManager = new ConfigManager({ ...this.defaultConfig, ...config }, hooks);
|
|
1668
|
+
this.gatekeeper = new HeuristicGatekeeper();
|
|
1669
|
+
this.sessionDNA = _IKFirewallCore.CONSTANTS.DNA.MIN;
|
|
1463
1670
|
const activeConfig = this.configManager.getConfig();
|
|
1464
1671
|
this.localProvider = new LocalProvider(activeConfig.localAuditEndpoint);
|
|
1465
1672
|
if (cloudProvider) {
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
const
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1673
|
+
this.cloudProvider = cloudProvider instanceof BaseProvider ? cloudProvider : new OpenAIProvider(cloudProvider);
|
|
1674
|
+
} else if (process.env.OPENAI_API_KEY) {
|
|
1675
|
+
this.cloudProvider = new OpenAIProvider(async (prompt, role) => {
|
|
1676
|
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
1677
|
+
method: "POST",
|
|
1678
|
+
headers: {
|
|
1679
|
+
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
|
|
1680
|
+
"Content-Type": "application/json"
|
|
1681
|
+
},
|
|
1682
|
+
body: JSON.stringify({
|
|
1683
|
+
model: role === "audit_layer" ? "gpt-4o-mini" : "gpt-4o",
|
|
1684
|
+
messages: [{ role: "user", content: prompt }],
|
|
1685
|
+
temperature: 0.1
|
|
1686
|
+
})
|
|
1687
|
+
});
|
|
1688
|
+
if (!response.ok) throw new Error(`OpenAI API Error: ${response.statusText}`);
|
|
1689
|
+
const data = await response.json();
|
|
1690
|
+
return {
|
|
1691
|
+
content: data.choices[0].message.content,
|
|
1692
|
+
usage: data.usage
|
|
1693
|
+
};
|
|
1694
|
+
});
|
|
1482
1695
|
}
|
|
1483
1696
|
this.orchestrator = new Orchestrator(this.configManager);
|
|
1484
|
-
this.usageTracker = new UsageTracker(this.configManager, this.
|
|
1697
|
+
this.usageTracker = new UsageTracker(this.configManager, this._hooks);
|
|
1698
|
+
}
|
|
1699
|
+
get hooks() {
|
|
1700
|
+
return this._hooks;
|
|
1701
|
+
}
|
|
1702
|
+
set hooks(newHooks) {
|
|
1703
|
+
this._hooks = newHooks;
|
|
1704
|
+
this.configManager.setHooks(newHooks);
|
|
1705
|
+
this.usageTracker.hooks = newHooks;
|
|
1485
1706
|
}
|
|
1486
1707
|
static getInstance(config, hooks) {
|
|
1487
1708
|
if (!_IKFirewallCore.instance) {
|
|
@@ -1593,7 +1814,14 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1593
1814
|
async analyze(input, provider, personaName = "professional", locale, instanceId) {
|
|
1594
1815
|
if (instanceId) {
|
|
1595
1816
|
this.configManager.ensureInstanceConfig(instanceId);
|
|
1596
|
-
|
|
1817
|
+
const syncPromise = this.configManager.syncRemoteConfig(instanceId).then(async () => {
|
|
1818
|
+
const pendingUsage = this.configManager._pendingUsage;
|
|
1819
|
+
if (pendingUsage && pendingUsage.length > 0) {
|
|
1820
|
+
await this.usageTracker.flush(pendingUsage);
|
|
1821
|
+
this.configManager._pendingUsage = null;
|
|
1822
|
+
}
|
|
1823
|
+
});
|
|
1824
|
+
await syncPromise;
|
|
1597
1825
|
}
|
|
1598
1826
|
const mergedConfig = this.configManager.getMergedConfig(instanceId);
|
|
1599
1827
|
if (instanceId && mergedConfig?.isVerified === false) {
|
|
@@ -1663,10 +1891,17 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1663
1891
|
throw e;
|
|
1664
1892
|
}
|
|
1665
1893
|
}
|
|
1666
|
-
|
|
1894
|
+
const cqScore = CognitiveEngine.sniffDNA(input);
|
|
1895
|
+
metrics.dm = Math.max(metrics.dm, cqScore / 10);
|
|
1896
|
+
this.applyHardening(input, metrics, activeLocale);
|
|
1667
1897
|
this.hooks?.onAuditComplete?.(metrics);
|
|
1668
1898
|
return metrics;
|
|
1669
1899
|
}
|
|
1900
|
+
applyHardening(input, metrics, locale = "en") {
|
|
1901
|
+
const archetype = metrics.semanticInsights?.archetype || "DYNAMIC";
|
|
1902
|
+
const domain = metrics.semanticInsights?.detectedDomain || "GENERAL";
|
|
1903
|
+
this.setSessionDNA(this.sessionDNA + 5);
|
|
1904
|
+
}
|
|
1670
1905
|
getEmptyMetrics() {
|
|
1671
1906
|
return {
|
|
1672
1907
|
dm: 0,
|
|
@@ -1718,28 +1953,6 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1718
1953
|
inputLength: input.length
|
|
1719
1954
|
};
|
|
1720
1955
|
}
|
|
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
1956
|
async analyzeAIAssisted(input, provider, personaName = "professional", instanceId, configOverride) {
|
|
1744
1957
|
if (instanceId) {
|
|
1745
1958
|
this.configManager.ensureInstanceConfig(instanceId);
|
|
@@ -1990,11 +2203,13 @@ Any action outside this scope MUST be rejected and flagged as a boundary violati
|
|
|
1990
2203
|
this.hooks?.onStatus?.(`\u{1F6E1}\uFE0F IK_CRYSTALLIZE: Precision domain detected (${domain}). Relaxing noise reduction...`);
|
|
1991
2204
|
archetypeModifier = -0.3;
|
|
1992
2205
|
}
|
|
2206
|
+
const cqScore = CognitiveEngine.sniffDNA(input);
|
|
2207
|
+
const cognitiveThreshold = CognitiveEngine.calculateThreshold(cqScore);
|
|
1993
2208
|
const threshold = Math.min(
|
|
1994
2209
|
_IKFirewallCore.CONSTANTS.AI.THRESHOLD_MAX,
|
|
1995
2210
|
Math.max(
|
|
1996
2211
|
_IKFirewallCore.CONSTANTS.AI.THRESHOLD_MIN,
|
|
1997
|
-
|
|
2212
|
+
cognitiveThreshold + archetypeModifier - tolerance * 0.1
|
|
1998
2213
|
)
|
|
1999
2214
|
);
|
|
2000
2215
|
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.1",
|
|
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
|
|