omnius 1.0.396 → 1.0.398
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.js +304 -75
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23474,28 +23474,28 @@ function countNodes(db) {
|
|
|
23474
23474
|
return 0;
|
|
23475
23475
|
}
|
|
23476
23476
|
}
|
|
23477
|
-
function
|
|
23477
|
+
function selectCapEvictionCandidates(db, options2, withText) {
|
|
23478
23478
|
const cap = Math.max(0, options2.graphTargetNodes ?? Number(process.env["OMNIUS_KG_TARGET_NODES"] ?? 5e3));
|
|
23479
23479
|
if (!Number.isFinite(cap) || cap <= 0)
|
|
23480
|
-
return
|
|
23480
|
+
return [];
|
|
23481
23481
|
const total = countNodes(db);
|
|
23482
23482
|
if (total <= cap)
|
|
23483
|
-
return
|
|
23483
|
+
return [];
|
|
23484
23484
|
const overflow = total - cap;
|
|
23485
23485
|
const batch2 = Math.min(overflow, options2.maxGraphDeletes ?? 2e3);
|
|
23486
23486
|
if (batch2 <= 0)
|
|
23487
|
-
return
|
|
23487
|
+
return [];
|
|
23488
23488
|
const now2 = Date.now();
|
|
23489
23489
|
const protectMs = Math.max(0, options2.graphProtectRecentMs ?? DAY);
|
|
23490
23490
|
const protectCut = now2 - protectMs;
|
|
23491
23491
|
const protect = new Set(options2.graphProtectNodeIds ?? []);
|
|
23492
23492
|
const hubDegreeGuard = 6;
|
|
23493
|
-
let candidates = [];
|
|
23494
23493
|
try {
|
|
23495
23494
|
const shortlistLimit = Math.max(1, Math.min(batch2 * 4, batch2 + 2e4));
|
|
23496
|
-
const
|
|
23497
|
-
|
|
23498
|
-
|
|
23495
|
+
const cols = withText ? `id, COALESCE(text, '') AS text, COALESCE(node_type, 'entity') AS nodeType,
|
|
23496
|
+
COALESCE(mention_count, 1) AS mc, COALESCE(last_seen, 0) AS ls` : `id, '' AS text, 'entity' AS nodeType,
|
|
23497
|
+
COALESCE(mention_count, 1) AS mc, COALESCE(last_seen, 0) AS ls`;
|
|
23498
|
+
const shortlist = db.prepare(`SELECT ${cols}
|
|
23499
23499
|
FROM kg_nodes
|
|
23500
23500
|
WHERE COALESCE(last_seen, 0) < ?
|
|
23501
23501
|
ORDER BY mc ASC, ls ASC
|
|
@@ -23513,19 +23513,70 @@ function pruneLowSignalNodesToCap(db, dbPath, options2) {
|
|
|
23513
23513
|
}
|
|
23514
23514
|
if (deg >= hubDegreeGuard)
|
|
23515
23515
|
continue;
|
|
23516
|
-
scored.push({
|
|
23516
|
+
scored.push({
|
|
23517
|
+
id: row.id,
|
|
23518
|
+
text: row.text,
|
|
23519
|
+
nodeType: row.nodeType,
|
|
23520
|
+
mentionCount: row.mc,
|
|
23521
|
+
degree: deg,
|
|
23522
|
+
lastSeen: row.ls,
|
|
23523
|
+
score: row.mc + deg * 2
|
|
23524
|
+
});
|
|
23517
23525
|
}
|
|
23518
|
-
scored.sort((a2, b) => a2.score - b.score || a2.
|
|
23519
|
-
|
|
23526
|
+
scored.sort((a2, b) => a2.score - b.score || a2.lastSeen - b.lastSeen);
|
|
23527
|
+
return scored.slice(0, batch2).map(({ score: _score, ...c9 }) => c9);
|
|
23520
23528
|
} catch {
|
|
23521
|
-
return
|
|
23529
|
+
return [];
|
|
23522
23530
|
}
|
|
23531
|
+
}
|
|
23532
|
+
function pruneLowSignalNodesToCap(db, dbPath, options2) {
|
|
23533
|
+
const candidates = selectCapEvictionCandidates(db, options2, false).map((c9) => c9.id);
|
|
23523
23534
|
if (candidates.length === 0)
|
|
23524
23535
|
return { nodes: 0, edges: 0, archived: 0 };
|
|
23525
23536
|
if (options2.dryRun)
|
|
23526
23537
|
return { nodes: candidates.length, edges: 0, archived: 0 };
|
|
23527
23538
|
return archiveAndDeleteNodes(db, dbPath, candidates, options2.graphArchive !== false);
|
|
23528
23539
|
}
|
|
23540
|
+
function selectGraphPruneCandidates(dbPath, options2) {
|
|
23541
|
+
if (!existsSync22(dbPath))
|
|
23542
|
+
return [];
|
|
23543
|
+
const db = initDb(dbPath);
|
|
23544
|
+
try {
|
|
23545
|
+
db.pragma("busy_timeout = 5000");
|
|
23546
|
+
return selectCapEvictionCandidates(db, options2, true);
|
|
23547
|
+
} catch {
|
|
23548
|
+
return [];
|
|
23549
|
+
} finally {
|
|
23550
|
+
try {
|
|
23551
|
+
db.close();
|
|
23552
|
+
} catch {
|
|
23553
|
+
}
|
|
23554
|
+
}
|
|
23555
|
+
}
|
|
23556
|
+
function reinforceGraphNodes(dbPath, ids) {
|
|
23557
|
+
if (!existsSync22(dbPath) || ids.length === 0)
|
|
23558
|
+
return 0;
|
|
23559
|
+
const db = initDb(dbPath);
|
|
23560
|
+
try {
|
|
23561
|
+
db.pragma("busy_timeout = 5000");
|
|
23562
|
+
const now2 = Date.now();
|
|
23563
|
+
const stmt = db.prepare("UPDATE kg_nodes SET last_seen = ?, mention_count = COALESCE(mention_count, 1) + 1 WHERE id = ?");
|
|
23564
|
+
let updated = 0;
|
|
23565
|
+
const tx = db.transaction((rows) => {
|
|
23566
|
+
for (const id of rows)
|
|
23567
|
+
updated += Number(stmt.run(now2, id).changes ?? 0);
|
|
23568
|
+
});
|
|
23569
|
+
tx(ids);
|
|
23570
|
+
return updated;
|
|
23571
|
+
} catch {
|
|
23572
|
+
return 0;
|
|
23573
|
+
} finally {
|
|
23574
|
+
try {
|
|
23575
|
+
db.close();
|
|
23576
|
+
} catch {
|
|
23577
|
+
}
|
|
23578
|
+
}
|
|
23579
|
+
}
|
|
23529
23580
|
function archiveAndDeleteNodes(db, dbPath, ids, archive) {
|
|
23530
23581
|
if (ids.length === 0)
|
|
23531
23582
|
return { nodes: 0, edges: 0, archived: 0 };
|
|
@@ -24414,6 +24465,7 @@ __export(dist_exports, {
|
|
|
24414
24465
|
reciprocityBias: () => reciprocityBias,
|
|
24415
24466
|
recordEmbeddingMeta: () => recordEmbeddingMeta,
|
|
24416
24467
|
reembedAll: () => reembedAll,
|
|
24468
|
+
reinforceGraphNodes: () => reinforceGraphNodes,
|
|
24417
24469
|
remDream: () => remDream,
|
|
24418
24470
|
resetCRLConfigStore: () => resetCRLConfigStore,
|
|
24419
24471
|
retrieveByPPR: () => retrieveByPPR,
|
|
@@ -24424,6 +24476,7 @@ __export(dist_exports, {
|
|
|
24424
24476
|
selectAndWalkGraphCandidate: () => selectAndWalkGraphCandidate,
|
|
24425
24477
|
selectAttentionContextItems: () => selectAttentionContextItems,
|
|
24426
24478
|
selectByAttention: () => selectByAttention,
|
|
24479
|
+
selectGraphPruneCandidates: () => selectGraphPruneCandidates,
|
|
24427
24480
|
selectInnerGraphCandidates: () => selectInnerGraphCandidates,
|
|
24428
24481
|
selfTrustFor: () => selfTrustFor,
|
|
24429
24482
|
shouldTriggerConsolidation: () => shouldTriggerConsolidation,
|
|
@@ -44414,12 +44467,12 @@ var init_identity2 = __esm({
|
|
|
44414
44467
|
function from2({ name: name10, code: code8, encode: encode15, minDigestLength, maxDigestLength }) {
|
|
44415
44468
|
return new Hasher(name10, code8, encode15, minDigestLength, maxDigestLength);
|
|
44416
44469
|
}
|
|
44417
|
-
function createDigest(digest3, code8,
|
|
44418
|
-
if (
|
|
44419
|
-
if (
|
|
44470
|
+
function createDigest(digest3, code8, truncate4) {
|
|
44471
|
+
if (truncate4 != null && truncate4 !== digest3.byteLength) {
|
|
44472
|
+
if (truncate4 > digest3.byteLength) {
|
|
44420
44473
|
throw new Error(`Invalid truncate option, must be less than or equal to ${digest3.byteLength}`);
|
|
44421
44474
|
}
|
|
44422
|
-
digest3 = digest3.subarray(0,
|
|
44475
|
+
digest3 = digest3.subarray(0, truncate4);
|
|
44423
44476
|
}
|
|
44424
44477
|
return create(code8, digest3);
|
|
44425
44478
|
}
|
|
@@ -77364,7 +77417,7 @@ var require_truncate = __commonJS({
|
|
|
77364
77417
|
function isLowSurrogate(codePoint) {
|
|
77365
77418
|
return codePoint >= 56320 && codePoint <= 57343;
|
|
77366
77419
|
}
|
|
77367
|
-
module.exports = function
|
|
77420
|
+
module.exports = function truncate4(getLength, string2, byteLength) {
|
|
77368
77421
|
if (typeof string2 !== "string") {
|
|
77369
77422
|
throw new Error("Input must be string");
|
|
77370
77423
|
}
|
|
@@ -77395,9 +77448,9 @@ var require_truncate = __commonJS({
|
|
|
77395
77448
|
var require_truncate_utf8_bytes = __commonJS({
|
|
77396
77449
|
"../node_modules/truncate-utf8-bytes/index.js"(exports, module) {
|
|
77397
77450
|
"use strict";
|
|
77398
|
-
var
|
|
77451
|
+
var truncate4 = require_truncate();
|
|
77399
77452
|
var getLength = Buffer.byteLength.bind(Buffer);
|
|
77400
|
-
module.exports =
|
|
77453
|
+
module.exports = truncate4.bind(null, getLength);
|
|
77401
77454
|
}
|
|
77402
77455
|
});
|
|
77403
77456
|
|
|
@@ -77405,7 +77458,7 @@ var require_truncate_utf8_bytes = __commonJS({
|
|
|
77405
77458
|
var require_sanitize_filename = __commonJS({
|
|
77406
77459
|
"../node_modules/sanitize-filename/index.js"(exports, module) {
|
|
77407
77460
|
"use strict";
|
|
77408
|
-
var
|
|
77461
|
+
var truncate4 = require_truncate_utf8_bytes();
|
|
77409
77462
|
var illegalRe = /[\/\?<>\\:\*\|"]/g;
|
|
77410
77463
|
var controlRe = /[\x00-\x1f\x80-\x9f]/g;
|
|
77411
77464
|
var reservedRe = /^\.+$/;
|
|
@@ -77421,7 +77474,7 @@ var require_sanitize_filename = __commonJS({
|
|
|
77421
77474
|
}
|
|
77422
77475
|
var sanitized = input.replace(illegalRe, replacement).replace(controlRe, replacement).replace(reservedRe, replacement).replace(windowsReservedRe, replacement);
|
|
77423
77476
|
sanitized = replaceTrailingDotsAndSpaces(sanitized, replacement);
|
|
77424
|
-
return
|
|
77477
|
+
return truncate4(sanitized, 255);
|
|
77425
77478
|
}
|
|
77426
77479
|
module.exports = function(input, options2) {
|
|
77427
77480
|
var replacement = options2 && options2.replacement || "";
|
|
@@ -599434,7 +599487,7 @@ function startIdleMemoryMaintenance(options2) {
|
|
|
599434
599487
|
const now2 = Date.now();
|
|
599435
599488
|
if (now2 - lastActivity < idleMs) return;
|
|
599436
599489
|
if (now2 - lastRunAt < minIntervalMs) return;
|
|
599437
|
-
worker2 = spawnWorker(options2
|
|
599490
|
+
worker2 = spawnWorker(options2);
|
|
599438
599491
|
if (!worker2) {
|
|
599439
599492
|
lastRunAt = now2;
|
|
599440
599493
|
return;
|
|
@@ -599463,7 +599516,8 @@ function startIdleMemoryMaintenance(options2) {
|
|
|
599463
599516
|
}
|
|
599464
599517
|
};
|
|
599465
599518
|
}
|
|
599466
|
-
function spawnWorker(
|
|
599519
|
+
function spawnWorker(options2) {
|
|
599520
|
+
const repoRoot = options2.repoRoot;
|
|
599467
599521
|
const stateDir = join120(repoRoot, ".omnius");
|
|
599468
599522
|
const maintenanceDir = join120(stateDir, "memory-maintenance");
|
|
599469
599523
|
mkdirSync64(maintenanceDir, { recursive: true });
|
|
@@ -599478,7 +599532,10 @@ function spawnWorker(repoRoot) {
|
|
|
599478
599532
|
cwd: repoRoot,
|
|
599479
599533
|
env: {
|
|
599480
599534
|
...process.env,
|
|
599481
|
-
OMNIUS_MEMORY_MAINTENANCE_STATE_DIR: stateDir
|
|
599535
|
+
OMNIUS_MEMORY_MAINTENANCE_STATE_DIR: stateDir,
|
|
599536
|
+
// Active idle inference for prune — only enabled when a model is provided.
|
|
599537
|
+
...options2.inferenceModel ? { OMNIUS_KG_PRUNE_MODEL: options2.inferenceModel } : {},
|
|
599538
|
+
...options2.inferenceBackendUrl ? { OMNIUS_KG_PRUNE_BACKEND_URL: options2.inferenceBackendUrl } : {}
|
|
599482
599539
|
},
|
|
599483
599540
|
stdio: ["ignore", "pipe", "pipe"]
|
|
599484
599541
|
});
|
|
@@ -605898,8 +605955,8 @@ var init_command_registry = __esm({
|
|
|
605898
605955
|
"Run memory maintenance: import deferred memory, prune episodes, compact graph stores"
|
|
605899
605956
|
],
|
|
605900
605957
|
[
|
|
605901
|
-
"/prune [now|dry|aggressive|stats] [--target <n>]",
|
|
605902
|
-
"Shrink knowledge.db: evict low-signal graph nodes (archived), then VACUUM. No arg opens the menu"
|
|
605958
|
+
"/prune [now|dry|infer|aggressive|stats] [--target <n>]",
|
|
605959
|
+
"Shrink knowledge.db: evict low-signal graph nodes (archived), then VACUUM. 'infer' = model-guided sleep consolidation. No arg opens the menu"
|
|
605903
605960
|
],
|
|
605904
605961
|
["/verbose", "Toggle verbose mode"],
|
|
605905
605962
|
["/clear", "Clear the screen"],
|
|
@@ -633702,6 +633759,88 @@ var init_mem_metabolize = __esm({
|
|
|
633702
633759
|
}
|
|
633703
633760
|
});
|
|
633704
633761
|
|
|
633762
|
+
// packages/cli/src/tui/commands/kg-prune-inference.ts
|
|
633763
|
+
function truncate3(text2, max) {
|
|
633764
|
+
const clean5 = text2.replace(/\s+/g, " ").trim();
|
|
633765
|
+
return clean5.length > max ? clean5.slice(0, max - 1) + "…" : clean5;
|
|
633766
|
+
}
|
|
633767
|
+
async function classifySignalNodes(candidates, cfg) {
|
|
633768
|
+
const max = Math.max(1, Math.min(cfg.maxCandidates ?? 40, 100));
|
|
633769
|
+
const sample = candidates.slice(0, max);
|
|
633770
|
+
if (sample.length === 0) return { reviewed: 0, keepIds: [], ok: true };
|
|
633771
|
+
if (!cfg.model || !cfg.backendUrl) {
|
|
633772
|
+
return { reviewed: 0, keepIds: [], ok: false, error: "no model/endpoint" };
|
|
633773
|
+
}
|
|
633774
|
+
const list = sample.map(
|
|
633775
|
+
(n2, i2) => `${i2 + 1}. id=${n2.id} type=${n2.nodeType} mentions=${n2.mentionCount} edges=${n2.degree} :: ${truncate3(n2.text, 160)}`
|
|
633776
|
+
).join("\n");
|
|
633777
|
+
const system = 'You are the memory-consolidation process of an AI agent, running during idle time (like sleep). You are shown low-activity knowledge-graph nodes that are scheduled to be FORGOTTEN to keep memory bounded. Your job: rescue only the ones that are durable SIGNAL — stable facts, real entities, decisions, identities, or reusable knowledge the agent will likely need again. Let transient, redundant, trivial, or noisy nodes be forgotten. Reply with ONLY a JSON array of the id strings to KEEP, e.g. ["a1","b2"]. Keep the array short and selective. If none are worth keeping, reply []';
|
|
633778
|
+
const user = `Nodes scheduled for forgetting:
|
|
633779
|
+
${list}
|
|
633780
|
+
|
|
633781
|
+
Return the JSON array of ids to KEEP.`;
|
|
633782
|
+
const timeoutMs = Math.max(3e3, cfg.timeoutMs ?? 3e4);
|
|
633783
|
+
try {
|
|
633784
|
+
const res = await fetch(`${cfg.backendUrl.replace(/\/$/, "")}/api/chat`, {
|
|
633785
|
+
method: "POST",
|
|
633786
|
+
headers: { "Content-Type": "application/json" },
|
|
633787
|
+
body: JSON.stringify({
|
|
633788
|
+
model: cfg.model,
|
|
633789
|
+
messages: [
|
|
633790
|
+
{ role: "system", content: system },
|
|
633791
|
+
{ role: "user", content: user }
|
|
633792
|
+
],
|
|
633793
|
+
stream: false,
|
|
633794
|
+
think: false,
|
|
633795
|
+
options: { temperature: 0 },
|
|
633796
|
+
keep_alive: "5m"
|
|
633797
|
+
}),
|
|
633798
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
633799
|
+
});
|
|
633800
|
+
if (!res.ok) {
|
|
633801
|
+
return {
|
|
633802
|
+
reviewed: sample.length,
|
|
633803
|
+
keepIds: [],
|
|
633804
|
+
ok: false,
|
|
633805
|
+
error: `HTTP ${res.status}`
|
|
633806
|
+
};
|
|
633807
|
+
}
|
|
633808
|
+
const data = await res.json();
|
|
633809
|
+
const content = data.message?.content ?? data.response ?? "";
|
|
633810
|
+
const keepIds = parseIdArray(content, new Set(sample.map((n2) => n2.id)));
|
|
633811
|
+
return { reviewed: sample.length, keepIds, ok: true };
|
|
633812
|
+
} catch (err) {
|
|
633813
|
+
return {
|
|
633814
|
+
reviewed: sample.length,
|
|
633815
|
+
keepIds: [],
|
|
633816
|
+
ok: false,
|
|
633817
|
+
error: err instanceof Error ? err.message : String(err)
|
|
633818
|
+
};
|
|
633819
|
+
}
|
|
633820
|
+
}
|
|
633821
|
+
function parseIdArray(content, valid) {
|
|
633822
|
+
const match = content.match(/\[[\s\S]*?\]/);
|
|
633823
|
+
if (!match) return [];
|
|
633824
|
+
let parsed;
|
|
633825
|
+
try {
|
|
633826
|
+
parsed = JSON.parse(match[0]);
|
|
633827
|
+
} catch {
|
|
633828
|
+
return [];
|
|
633829
|
+
}
|
|
633830
|
+
if (!Array.isArray(parsed)) return [];
|
|
633831
|
+
const out = [];
|
|
633832
|
+
for (const item of parsed) {
|
|
633833
|
+
const id = typeof item === "string" ? item : String(item ?? "");
|
|
633834
|
+
if (id && valid.has(id) && !out.includes(id)) out.push(id);
|
|
633835
|
+
}
|
|
633836
|
+
return out;
|
|
633837
|
+
}
|
|
633838
|
+
var init_kg_prune_inference = __esm({
|
|
633839
|
+
"packages/cli/src/tui/commands/kg-prune-inference.ts"() {
|
|
633840
|
+
"use strict";
|
|
633841
|
+
}
|
|
633842
|
+
});
|
|
633843
|
+
|
|
633705
633844
|
// packages/cli/src/tui/commands/kg-prune.ts
|
|
633706
633845
|
var kg_prune_exports = {};
|
|
633707
633846
|
__export(kg_prune_exports, {
|
|
@@ -633709,7 +633848,8 @@ __export(kg_prune_exports, {
|
|
|
633709
633848
|
formatBytes: () => formatBytes10,
|
|
633710
633849
|
formatKgStatsLine: () => formatKgStatsLine,
|
|
633711
633850
|
knowledgeGraphStats: () => knowledgeGraphStats,
|
|
633712
|
-
pruneKnowledgeGraph: () => pruneKnowledgeGraph
|
|
633851
|
+
pruneKnowledgeGraph: () => pruneKnowledgeGraph,
|
|
633852
|
+
pruneKnowledgeGraphWithInference: () => pruneKnowledgeGraphWithInference
|
|
633713
633853
|
});
|
|
633714
633854
|
import { existsSync as existsSync130, statSync as statSync49 } from "node:fs";
|
|
633715
633855
|
import { join as join142 } from "node:path";
|
|
@@ -633772,6 +633912,7 @@ function pruneKnowledgeGraph(opts) {
|
|
|
633772
633912
|
vacuum: true,
|
|
633773
633913
|
graphTargetNodes: target,
|
|
633774
633914
|
graphArchive: opts.archive ?? true,
|
|
633915
|
+
graphProtectNodeIds: opts.protectNodeIds,
|
|
633775
633916
|
maxGraphNodes: 12e3,
|
|
633776
633917
|
maxGraphDeletes: opts.maxDeletes ?? 5e3,
|
|
633777
633918
|
maxRuntimeMs: opts.maxRuntimeMs ?? 10 * 6e4
|
|
@@ -633793,6 +633934,47 @@ function pruneKnowledgeGraph(opts) {
|
|
|
633793
633934
|
].filter(Boolean).join("\n");
|
|
633794
633935
|
return { report: report2, result };
|
|
633795
633936
|
}
|
|
633937
|
+
async function pruneKnowledgeGraphWithInference(opts) {
|
|
633938
|
+
const stateDir = stateDirFor(opts.workingDir);
|
|
633939
|
+
const knowledgePath = join142(stateDir, "knowledge.db");
|
|
633940
|
+
if (!existsSync130(knowledgePath)) {
|
|
633941
|
+
return {
|
|
633942
|
+
report: `No knowledge.db found at ${stateDir}. Nothing to prune.`,
|
|
633943
|
+
result: null
|
|
633944
|
+
};
|
|
633945
|
+
}
|
|
633946
|
+
const target = opts.targetNodes ?? DEFAULT_KG_TARGET_NODES;
|
|
633947
|
+
const candidates = selectGraphPruneCandidates(knowledgePath, {
|
|
633948
|
+
stateDir,
|
|
633949
|
+
graphTargetNodes: target,
|
|
633950
|
+
maxGraphDeletes: opts.maxDeletes ?? 5e3
|
|
633951
|
+
});
|
|
633952
|
+
let inferenceLine = " Inference: no candidates over target — nothing to review.";
|
|
633953
|
+
let protectIds = [];
|
|
633954
|
+
if (candidates.length > 0) {
|
|
633955
|
+
const cls = await classifySignalNodes(candidates, {
|
|
633956
|
+
backendUrl: opts.backendUrl,
|
|
633957
|
+
model: opts.model,
|
|
633958
|
+
maxCandidates: opts.maxCandidates ?? 40,
|
|
633959
|
+
timeoutMs: opts.timeoutMs
|
|
633960
|
+
});
|
|
633961
|
+
if (cls.ok) {
|
|
633962
|
+
protectIds = cls.keepIds;
|
|
633963
|
+
if (!opts.dryRun && protectIds.length > 0) {
|
|
633964
|
+
reinforceGraphNodes(knowledgePath, protectIds);
|
|
633965
|
+
}
|
|
633966
|
+
inferenceLine = ` Inference: reviewed ${cls.reviewed} candidates · kept ${protectIds.length} as signal (reinforced${opts.dryRun ? " skipped (dry-run)" : ""}).`;
|
|
633967
|
+
} else {
|
|
633968
|
+
inferenceLine = ` Inference: unavailable (${cls.error ?? "error"}) — mechanical prune only.`;
|
|
633969
|
+
}
|
|
633970
|
+
}
|
|
633971
|
+
const { report: report2, result } = pruneKnowledgeGraph({
|
|
633972
|
+
...opts,
|
|
633973
|
+
protectNodeIds: protectIds
|
|
633974
|
+
});
|
|
633975
|
+
return { report: `${report2}
|
|
633976
|
+
${inferenceLine}`, result };
|
|
633977
|
+
}
|
|
633796
633978
|
function formatBytes10(bytes) {
|
|
633797
633979
|
if (bytes < 1024) return `${bytes} B`;
|
|
633798
633980
|
const units = ["KB", "MB", "GB", "TB"];
|
|
@@ -633814,6 +633996,7 @@ var init_kg_prune = __esm({
|
|
|
633814
633996
|
"packages/cli/src/tui/commands/kg-prune.ts"() {
|
|
633815
633997
|
"use strict";
|
|
633816
633998
|
init_dist();
|
|
633999
|
+
init_kg_prune_inference();
|
|
633817
634000
|
DEFAULT_KG_TARGET_NODES = Number(
|
|
633818
634001
|
process.env["OMNIUS_KG_TARGET_NODES"] ?? 5e3
|
|
633819
634002
|
);
|
|
@@ -633851,6 +634034,13 @@ async function showPruneMenu(options2) {
|
|
|
633851
634034
|
label: import_chalk2.default.yellow("Aggressive full prune"),
|
|
633852
634035
|
detail: "Larger delete budget + longer time budget — for a first cleanup of a large DB."
|
|
633853
634036
|
},
|
|
634037
|
+
...options2.model ? [
|
|
634038
|
+
{
|
|
634039
|
+
key: "infer",
|
|
634040
|
+
label: import_chalk2.default.blueBright("Sleep consolidation (inference)"),
|
|
634041
|
+
detail: "Ask the model which about-to-be-forgotten nodes are signal; reinforce those, forget the rest."
|
|
634042
|
+
}
|
|
634043
|
+
] : [],
|
|
633854
634044
|
{ key: "sep1", label: import_chalk2.default.gray("─".repeat(34)) },
|
|
633855
634045
|
{
|
|
633856
634046
|
key: "stats",
|
|
@@ -633892,6 +634082,19 @@ async function showPruneMenu(options2) {
|
|
|
633892
634082
|
renderInfo(report2);
|
|
633893
634083
|
break;
|
|
633894
634084
|
}
|
|
634085
|
+
case "infer": {
|
|
634086
|
+
if (!options2.model) break;
|
|
634087
|
+
renderInfo(
|
|
634088
|
+
"Sleep consolidation — reviewing low-signal nodes with the model…"
|
|
634089
|
+
);
|
|
634090
|
+
const { report: report2 } = await pruneKnowledgeGraphWithInference({
|
|
634091
|
+
workingDir,
|
|
634092
|
+
model: options2.model,
|
|
634093
|
+
backendUrl: options2.backendUrl ?? "http://127.0.0.1:11434"
|
|
634094
|
+
});
|
|
634095
|
+
renderInfo(report2);
|
|
634096
|
+
break;
|
|
634097
|
+
}
|
|
633895
634098
|
case "stats": {
|
|
633896
634099
|
renderInfo(formatKgStatsLine(knowledgeGraphStats(workingDir)));
|
|
633897
634100
|
await showPruneMenu(options2);
|
|
@@ -643287,7 +643490,12 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
643287
643490
|
} = await Promise.resolve().then(() => (init_kg_prune(), kg_prune_exports));
|
|
643288
643491
|
if (!sub2 || sub2 === "menu") {
|
|
643289
643492
|
const { showPruneMenu: showPruneMenu2 } = await Promise.resolve().then(() => (init_prune_menu(), prune_menu_exports));
|
|
643290
|
-
await showPruneMenu2({
|
|
643493
|
+
await showPruneMenu2({
|
|
643494
|
+
rl: ctx3.rl,
|
|
643495
|
+
workingDir,
|
|
643496
|
+
model: ctx3.config.model,
|
|
643497
|
+
backendUrl: ctx3.config.backendUrl
|
|
643498
|
+
});
|
|
643291
643499
|
return "handled";
|
|
643292
643500
|
}
|
|
643293
643501
|
if (sub2 === "stats") {
|
|
@@ -643312,6 +643520,18 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
643312
643520
|
);
|
|
643313
643521
|
return "handled";
|
|
643314
643522
|
}
|
|
643523
|
+
if (sub2 === "infer" || sub2 === "inference" || sub2 === "sleep") {
|
|
643524
|
+
const { pruneKnowledgeGraphWithInference: pruneKnowledgeGraphWithInference2 } = await Promise.resolve().then(() => (init_kg_prune(), kg_prune_exports));
|
|
643525
|
+
renderInfo("Sleep consolidation — reviewing low-signal nodes with the model…");
|
|
643526
|
+
const { report: report2 } = await pruneKnowledgeGraphWithInference2({
|
|
643527
|
+
workingDir,
|
|
643528
|
+
targetNodes,
|
|
643529
|
+
model: ctx3.config.model,
|
|
643530
|
+
backendUrl: ctx3.config.backendUrl
|
|
643531
|
+
});
|
|
643532
|
+
renderInfo(report2);
|
|
643533
|
+
return "handled";
|
|
643534
|
+
}
|
|
643315
643535
|
renderInfo("Pruning knowledge graph…");
|
|
643316
643536
|
renderInfo(pruneKnowledgeGraph2({ workingDir, targetNodes }).report);
|
|
643317
643537
|
return "handled";
|
|
@@ -721598,12 +721818,12 @@ function getRuntimeToolProfilePolicy(repoRoot) {
|
|
|
721598
721818
|
return profile ? profilePolicy(profile) : void 0;
|
|
721599
721819
|
}
|
|
721600
721820
|
function formatSubAgentEventForView(event) {
|
|
721601
|
-
const
|
|
721821
|
+
const truncate4 = (s2, n2) => s2.length > n2 ? `${s2.slice(0, n2)}…` : s2;
|
|
721602
721822
|
switch (event.type) {
|
|
721603
721823
|
case "tool_call": {
|
|
721604
721824
|
let args = "";
|
|
721605
721825
|
try {
|
|
721606
|
-
args = event.toolArgs ?
|
|
721826
|
+
args = event.toolArgs ? truncate4(JSON.stringify(event.toolArgs), 120) : "";
|
|
721607
721827
|
} catch {
|
|
721608
721828
|
args = "";
|
|
721609
721829
|
}
|
|
@@ -721612,24 +721832,24 @@ function formatSubAgentEventForView(event) {
|
|
|
721612
721832
|
case "tool_result": {
|
|
721613
721833
|
const mark = event.success === false ? "✗" : "✓";
|
|
721614
721834
|
const body = (event.content ?? "").split("\n").slice(0, 3).join(" ").trim();
|
|
721615
|
-
return `${mark} ${event.toolName ?? "tool"}${body ? `: ${
|
|
721835
|
+
return `${mark} ${event.toolName ?? "tool"}${body ? `: ${truncate4(body, 300)}` : ""}`;
|
|
721616
721836
|
}
|
|
721617
721837
|
case "assistant_text":
|
|
721618
721838
|
case "model_response": {
|
|
721619
721839
|
const t2 = (event.content ?? "").trim();
|
|
721620
|
-
return t2 ?
|
|
721840
|
+
return t2 ? truncate4(t2, 1e3) : null;
|
|
721621
721841
|
}
|
|
721622
721842
|
case "status": {
|
|
721623
721843
|
const t2 = (event.content ?? "").trim();
|
|
721624
|
-
return t2 ? `· ${
|
|
721844
|
+
return t2 ? `· ${truncate4(t2, 300)}` : null;
|
|
721625
721845
|
}
|
|
721626
721846
|
case "error": {
|
|
721627
721847
|
const t2 = (event.content ?? "").trim();
|
|
721628
|
-
return t2 ? `✗ ${
|
|
721848
|
+
return t2 ? `✗ ${truncate4(t2, 400)}` : null;
|
|
721629
721849
|
}
|
|
721630
721850
|
case "complete": {
|
|
721631
721851
|
const t2 = (event.content ?? "").trim();
|
|
721632
|
-
return t2 ? `✓ ${
|
|
721852
|
+
return t2 ? `✓ ${truncate4(t2, 400)}` : null;
|
|
721633
721853
|
}
|
|
721634
721854
|
default:
|
|
721635
721855
|
return null;
|
|
@@ -723739,45 +723959,49 @@ ${entry.fullContent}`
|
|
|
723739
723959
|
`
|
|
723740
723960
|
);
|
|
723741
723961
|
} else {
|
|
723742
|
-
|
|
723743
|
-
|
|
723744
|
-
|
|
723745
|
-
|
|
723746
|
-
|
|
723747
|
-
|
|
723748
|
-
|
|
723749
|
-
|
|
723750
|
-
|
|
723751
|
-
|
|
723752
|
-
|
|
723753
|
-
|
|
723754
|
-
|
|
723755
|
-
|
|
723756
|
-
|
|
723757
|
-
|
|
723758
|
-
|
|
723759
|
-
|
|
723760
|
-
|
|
723761
|
-
|
|
723762
|
-
|
|
723763
|
-
|
|
723764
|
-
|
|
723765
|
-
|
|
723766
|
-
|
|
723767
|
-
|
|
723768
|
-
|
|
723769
|
-
const
|
|
723770
|
-
|
|
723771
|
-
|
|
723772
|
-
|
|
723773
|
-
|
|
723774
|
-
id,
|
|
723775
|
-
|
|
723776
|
-
|
|
723777
|
-
|
|
723778
|
-
|
|
723779
|
-
|
|
723780
|
-
|
|
723962
|
+
renderToolCallStart(
|
|
723963
|
+
event.toolName ?? "unknown",
|
|
723964
|
+
event.toolArgs ?? {},
|
|
723965
|
+
config.verbose
|
|
723966
|
+
);
|
|
723967
|
+
const wantsVoice = !!voice?.enabled && (voice.voiceMode === "action" || voice.voiceMode === "verbose");
|
|
723968
|
+
const wantsShellLive = event.toolName === "shell" && !!statusBar?.isActive;
|
|
723969
|
+
if (wantsVoice || wantsShellLive) {
|
|
723970
|
+
contentWrite(() => {
|
|
723971
|
+
if (wantsVoice && voice) {
|
|
723972
|
+
const emoState = emotionEngine?.getState();
|
|
723973
|
+
const emoCtx = emoState ? {
|
|
723974
|
+
valence: emoState.valence,
|
|
723975
|
+
arousal: emoState.arousal,
|
|
723976
|
+
label: emoState.label,
|
|
723977
|
+
emoji: emoState.emoji
|
|
723978
|
+
} : void 0;
|
|
723979
|
+
const desc = describeToolCall(
|
|
723980
|
+
event.toolName ?? "unknown",
|
|
723981
|
+
event.toolArgs ?? {},
|
|
723982
|
+
vLevel,
|
|
723983
|
+
emoCtx,
|
|
723984
|
+
isStark
|
|
723985
|
+
);
|
|
723986
|
+
renderVoiceText(desc);
|
|
723987
|
+
voice.speakSubordinate(desc, emoCtx);
|
|
723988
|
+
}
|
|
723989
|
+
const liveShellStatusBar = statusBar;
|
|
723990
|
+
if (wantsShellLive && liveShellStatusBar) {
|
|
723991
|
+
const command = String(event.toolArgs?.command ?? "");
|
|
723992
|
+
const state = createShellLiveBlockState(command);
|
|
723993
|
+
const id = `shell-live-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
723994
|
+
liveShellBlock = { id, state, repaintTimer: null };
|
|
723995
|
+
lastLiveShellPaint = "";
|
|
723996
|
+
liveShellStatusBar.registerDynamicBlock(
|
|
723997
|
+
id,
|
|
723998
|
+
(width) => buildShellLiveBlockLines(state, width)
|
|
723999
|
+
);
|
|
724000
|
+
liveShellStatusBar.appendDynamicBlock(id);
|
|
724001
|
+
scheduleLiveShellRepaint();
|
|
724002
|
+
}
|
|
724003
|
+
});
|
|
724004
|
+
}
|
|
723781
724005
|
}
|
|
723782
724006
|
if (event.toolName) sessionToolsUsed.add(event.toolName);
|
|
723783
724007
|
break;
|
|
@@ -725700,7 +725924,12 @@ Rationale: ${proposal.rationale}${provenanceNote}${dmnDevDiscipline(proposal.cat
|
|
|
725700
725924
|
if (!summary) return;
|
|
725701
725925
|
writeContent(() => renderInfo(summary));
|
|
725702
725926
|
if (!activeTask) showPrompt();
|
|
725703
|
-
}
|
|
725927
|
+
},
|
|
725928
|
+
// Active idle inference for KG prune ("sleep consolidation"). Uses the
|
|
725929
|
+
// configured backend/model to decide which about-to-be-forgotten nodes are
|
|
725930
|
+
// signal. Disable with OMNIUS_KG_PRUNE_INFERENCE=0.
|
|
725931
|
+
inferenceModel: config.model,
|
|
725932
|
+
inferenceBackendUrl: config.backendUrl
|
|
725704
725933
|
});
|
|
725705
725934
|
const setActiveTaskContextWindowSize = (size) => {
|
|
725706
725935
|
const runner = activeTask?.runner;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.398",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.398",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED