renor-engine 0.0.0-stage → 1.0.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/LICENSE +661 -0
- package/NOTICE +73 -0
- package/README.md +105 -2
- package/dist/BUILD.json +6 -0
- package/dist/api/apiAuth.js +43 -0
- package/dist/api/server.js +172 -0
- package/dist/buildIdentity.js +132 -0
- package/dist/cli-extractors.js +46 -0
- package/dist/cli.js +491 -0
- package/dist/config.js +65 -0
- package/dist/context/composer.js +320 -0
- package/dist/context/readHonesty.js +478 -0
- package/dist/context/rowStore.js +238 -0
- package/dist/conversation/formatter.js +81 -0
- package/dist/conversation/parser.js +189 -0
- package/dist/conversation/types.js +2 -0
- package/dist/conversation/writer.js +42 -0
- package/dist/db/client.js +147 -0
- package/dist/db/indexSalvage.js +81 -0
- package/dist/db/migrations.js +642 -0
- package/dist/db/readCache.js +109 -0
- package/dist/db/schema.js +5 -0
- package/dist/db/statements.js +89 -0
- package/dist/digests/digestCache.js +142 -0
- package/dist/digests/digests.js +597 -0
- package/dist/digests/worker.js +348 -0
- package/dist/embeddings/caching.js +337 -0
- package/dist/embeddings/coalescing.js +177 -0
- package/dist/embeddings/interactive.js +103 -0
- package/dist/embeddings/local.js +68 -0
- package/dist/embeddings/openai.js +105 -0
- package/dist/embeddings/rebuild.js +166 -0
- package/dist/embeddings/simdScan.js +258 -0
- package/dist/embeddings/space.js +21 -0
- package/dist/embeddings/types.js +14 -0
- package/dist/embeddings/vectorIndex.js +675 -0
- package/dist/embeddings/vertex.js +224 -0
- package/dist/eval/artifacts.js +42 -0
- package/dist/eval/cacheReport.js +139 -0
- package/dist/eval/comparison.js +182 -0
- package/dist/eval/context700-candidate.js +145 -0
- package/dist/eval/evalCache.js +525 -0
- package/dist/eval/hashEmbedding.js +35 -0
- package/dist/eval/longmemeval.js +56 -0
- package/dist/eval/metrics.js +181 -0
- package/dist/eval/renorbenchBaseline.js +486 -0
- package/dist/eval/renorbenchDocuments.js +134 -0
- package/dist/eval/renorbenchProduct.js +182 -0
- package/dist/eval/runLedger.js +279 -0
- package/dist/eval/runManifest.js +479 -0
- package/dist/eval/scoring.js +197 -0
- package/dist/evidence/attach.js +267 -0
- package/dist/evidence/background.js +147 -0
- package/dist/evidence/evidenceCache.js +182 -0
- package/dist/evidence/gate.js +37 -0
- package/dist/evidence/keyPool.js +85 -0
- package/dist/evidence/ollamaChat.js +84 -0
- package/dist/evidence/optin.js +165 -0
- package/dist/evidence/options.js +130 -0
- package/dist/evidence/secondPass.js +456 -0
- package/dist/extraction/classifyCapture.js +34 -0
- package/dist/extraction/decision-model.js +174 -0
- package/dist/extraction/eventExtractor.js +113 -0
- package/dist/extraction/extractionClient.js +122 -0
- package/dist/extraction/factExtractor.js +46 -0
- package/dist/extraction/factsWritePath.js +179 -0
- package/dist/extraction/preferenceExtractor.js +153 -0
- package/dist/extraction/secretGuard.js +176 -0
- package/dist/extraction/secretScanner.js +665 -0
- package/dist/extraction/typedFacts.js +224 -0
- package/dist/extraction/writePathAdjudication.js +110 -0
- package/dist/importing/apply.js +644 -0
- package/dist/importing/bundle-write.js +80 -0
- package/dist/importing/cli.js +407 -0
- package/dist/importing/existing.js +49 -0
- package/dist/importing/facts.js +123 -0
- package/dist/importing/forgetImported.js +79 -0
- package/dist/importing/hosted.js +467 -0
- package/dist/importing/index.js +29 -0
- package/dist/importing/journalLog.js +96 -0
- package/dist/importing/markdown.js +98 -0
- package/dist/importing/plan.js +206 -0
- package/dist/importing/secretScreen.js +113 -0
- package/dist/importing/serialize.js +188 -0
- package/dist/importing/source.js +463 -0
- package/dist/importing/types.js +6 -0
- package/dist/indexer/chunker.js +319 -0
- package/dist/indexer/dailyEntries.js +63 -0
- package/dist/indexer/hasher.js +10 -0
- package/dist/indexer/laneRuns.js +48 -0
- package/dist/indexer/o200k.js +481 -0
- package/dist/indexer/o200k.json +8 -0
- package/dist/indexer/outsideRoot.js +77 -0
- package/dist/indexer/parser.js +167 -0
- package/dist/indexer/pipeline.js +1168 -0
- package/dist/indexer/staleness.js +201 -0
- package/dist/indexer/tokenizer.js +77 -0
- package/dist/indexer/walker.js +184 -0
- package/dist/mcp/hive.js +88 -0
- package/dist/mcp/requestErrors.js +47 -0
- package/dist/mcp/server.js +396 -0
- package/dist/memory/agentLease.js +43 -0
- package/dist/memory/confinedWrite.js +315 -0
- package/dist/memory/controls.js +73 -0
- package/dist/memory/dailyNote.js +265 -0
- package/dist/memory/durableAppend.js +57 -0
- package/dist/memory/factConflicts.js +203 -0
- package/dist/memory/factTerms.js +321 -0
- package/dist/memory/hiveNameHeader.cjs +10 -0
- package/dist/memory/inventory.js +55 -0
- package/dist/memory/invisibleText.js +20 -0
- package/dist/memory/lifecycle.js +1756 -0
- package/dist/memory/limits.js +13 -0
- package/dist/memory/requests.js +183 -0
- package/dist/memory/sourceName.js +200 -0
- package/dist/memory/whatsNew.js +158 -0
- package/dist/memory/writer.js +175 -0
- package/dist/memory/writerConflicts.js +85 -0
- package/dist/memorymap/memoryMap.js +1568 -0
- package/dist/memorymap/replacedJournal.js +58 -0
- package/dist/memorymap/replacements.js +405 -0
- package/dist/mvp/activity.js +86 -0
- package/dist/mvp/agentMemory.js +1744 -0
- package/dist/mvp/auth.js +531 -0
- package/dist/mvp/cli.js +73 -0
- package/dist/mvp/client-store.js +462 -0
- package/dist/mvp/compileCache.js +249 -0
- package/dist/mvp/compileSeed.js +27 -0
- package/dist/mvp/config.js +288 -0
- package/dist/mvp/connectionStatus.js +80 -0
- package/dist/mvp/contextRelevance.js +413 -0
- package/dist/mvp/engine.js +1065 -0
- package/dist/mvp/exportAll.js +359 -0
- package/dist/mvp/factLanePack.js +77 -0
- package/dist/mvp/factMarkers.js +49 -0
- package/dist/mvp/factsLane.js +203 -0
- package/dist/mvp/hiddenSpans.js +585 -0
- package/dist/mvp/history.js +413 -0
- package/dist/mvp/hitDates.js +31 -0
- package/dist/mvp/hitFloor.js +36 -0
- package/dist/mvp/identity.js +18 -0
- package/dist/mvp/idle.js +113 -0
- package/dist/mvp/memoryDir.js +98 -0
- package/dist/mvp/posthogMcp.js +210 -0
- package/dist/mvp/readScope.js +104 -0
- package/dist/mvp/readUsefulness.js +222 -0
- package/dist/mvp/sanitize.js +48 -0
- package/dist/mvp/schemaRejections.js +91 -0
- package/dist/mvp/scope.js +127 -0
- package/dist/mvp/server.js +2089 -0
- package/dist/mvp/serverCard.js +29 -0
- package/dist/mvp/storedSize.js +139 -0
- package/dist/mvp/telemetry.js +441 -0
- package/dist/retrieval/adviceLines.js +195 -0
- package/dist/retrieval/adviceQuestion.js +44 -0
- package/dist/retrieval/conversationShape.js +44 -0
- package/dist/retrieval/dailyEntryTime.js +55 -0
- package/dist/retrieval/entityLookup.js +113 -0
- package/dist/retrieval/factsFirst.js +188 -0
- package/dist/retrieval/keyword.js +84 -0
- package/dist/retrieval/ledgerEventTime.js +51 -0
- package/dist/retrieval/ledgerLiveness.js +83 -0
- package/dist/retrieval/ledgerPresentation.js +161 -0
- package/dist/retrieval/noteIdentity.js +57 -0
- package/dist/retrieval/orchestrator.js +1086 -0
- package/dist/retrieval/queryHelpers.js +142 -0
- package/dist/retrieval/questionSpan.js +475 -0
- package/dist/retrieval/readerEvents.js +690 -0
- package/dist/retrieval/readerLayout.js +503 -0
- package/dist/retrieval/relativeTimeHints.js +113 -0
- package/dist/retrieval/semantic.js +67 -0
- package/dist/router/routerCache.js +106 -0
- package/dist/router/sessionRouter.js +726 -0
- package/dist/toolRefusal.js +120 -0
- package/dist/watcher/watcher.js +75 -0
- package/package.json +120 -4
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.byPlace = byPlace;
|
|
4
|
+
exports.byScoreThenPlace = byScoreThenPlace;
|
|
5
|
+
exports.semanticSearch = semanticSearch;
|
|
6
|
+
const readCache_1 = require("../db/readCache");
|
|
7
|
+
const statements_1 = require("../db/statements");
|
|
8
|
+
/**
|
|
9
|
+
* Note path, then chunk id: the order of chunks whose scores are equal. A note's chunks are written top to bottom (by
|
|
10
|
+
* the indexer, and by the importer, which copies them in that order), so within one note the id is the chunk's place,
|
|
11
|
+
* the same in every index of the same notes. Across notes ids are not: they follow the order indexing wrote the notes
|
|
12
|
+
* in, which concurrent indexing does not fix.
|
|
13
|
+
*/
|
|
14
|
+
function byPlace(a, b) {
|
|
15
|
+
if (a.notePath !== b.notePath)
|
|
16
|
+
return a.notePath < b.notePath ? -1 : 1;
|
|
17
|
+
return a.chunkId - b.chunkId;
|
|
18
|
+
}
|
|
19
|
+
/** Highest score first; equal scores by place (`byPlace`). */
|
|
20
|
+
function byScoreThenPlace(a, b) {
|
|
21
|
+
return b.score - a.score || byPlace(a, b);
|
|
22
|
+
}
|
|
23
|
+
async function semanticSearch(db, vectorIndex, provider, query, topK, probe,
|
|
24
|
+
/** Only the chunks it shows are candidates: the nearest `topK` of them, however many others are nearer. */
|
|
25
|
+
scope) {
|
|
26
|
+
// A fresh/empty memory has nothing to compare against. Avoid paying the
|
|
27
|
+
// provider/network cost for a query embedding that cannot produce a hit.
|
|
28
|
+
// Ask vec0's rowid shadow table, not the virtual table: `SELECT ... FROM chunk_embeddings` without a
|
|
29
|
+
// MATCH walks every vector (milliseconds at 10,000 notes, growing with the index) to learn "not empty".
|
|
30
|
+
// `chunk_embeddings_rowids` holds one row per stored vector.
|
|
31
|
+
const hasVectors = (0, statements_1.prepareOnce)(db, 'SELECT 1 FROM chunk_embeddings_rowids LIMIT 1').get();
|
|
32
|
+
if (!hasVectors || topK <= 0)
|
|
33
|
+
return [];
|
|
34
|
+
const queryEmbedding = provider.embedQuery
|
|
35
|
+
? await provider.embedQuery(query)
|
|
36
|
+
: (await provider.embed([query]))[0];
|
|
37
|
+
if (probe)
|
|
38
|
+
probe.queryVector = queryEmbedding;
|
|
39
|
+
// The chunks of the `k` nearest vectors (of those `among` names, when it is given), best first, and how many vectors
|
|
40
|
+
// were read: more than `k` when the farthest of them is tied, and the cut is made by place, not by where vectors are
|
|
41
|
+
// stored; fewer only when there are no more.
|
|
42
|
+
const nearest = (k, among) => {
|
|
43
|
+
const hits = vectorIndex.search(queryEmbedding, k, among);
|
|
44
|
+
if (hits.length === 0)
|
|
45
|
+
return { vectors: 0, chunks: [] };
|
|
46
|
+
const scoreMap = new Map(hits.map(h => [h.chunkId, h.score]));
|
|
47
|
+
const rows = (0, statements_1.prepareOnce)(db, `SELECT id, note_path, heading_path, text, start_line, end_line FROM chunks WHERE id IN (SELECT value FROM json_each(?))`).all(JSON.stringify(hits.map(h => h.chunkId)));
|
|
48
|
+
return {
|
|
49
|
+
vectors: hits.length,
|
|
50
|
+
chunks: rows
|
|
51
|
+
.map(r => ({ notePath: r.note_path, chunkId: r.id, headingPath: r.heading_path, text: r.text, score: scoreMap.get(r.id) ?? 0, startLine: r.start_line, endLine: r.end_line }))
|
|
52
|
+
.sort(byScoreThenPlace),
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
// The query is embedded: nothing below waits for anything, so the nearest chunks are read in one transaction (inReadSnapshot).
|
|
56
|
+
return (0, readCache_1.inReadSnapshot)(db, () => {
|
|
57
|
+
if (!scope)
|
|
58
|
+
return nearest(topK).chunks.slice(0, topK);
|
|
59
|
+
// Judged before the cut: when fewer than `topK` of the nearest chunks are shown (other chunks are nearer), the nearest
|
|
60
|
+
// of the shown chunks themselves are read instead, so however many others are nearer, none takes their places.
|
|
61
|
+
const first = nearest(topK);
|
|
62
|
+
const shown = first.chunks.filter(scope.shows);
|
|
63
|
+
if (shown.length >= topK || first.vectors < topK)
|
|
64
|
+
return shown.slice(0, topK);
|
|
65
|
+
return nearest(topK, scope.chunkIds()).chunks.slice(0, topK);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RouterCache = exports.ROUTER_CACHE_SCHEMA_VERSION = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
11
|
+
/**
|
|
12
|
+
* Content-addressed cache for the session router (RENOR_SESSION_ROUTER, src/router/sessionRouter.ts): the
|
|
13
|
+
* per-note summaries the router reads, and the router's own answers.
|
|
14
|
+
*
|
|
15
|
+
* summary key = sha256(schema \0 'summary' \0 model \0 sha256(summary prompt template) \0 note_hash)
|
|
16
|
+
* route key = sha256(schema \0 'route' \0 model \0 exact rendered routing prompt)
|
|
17
|
+
*
|
|
18
|
+
* A note's summary is keyed by the hash of the note's file (the index's `note_hash`), so an edited note gets a new
|
|
19
|
+
* summary and an unchanged one is never paid for twice; a changed prompt template invalidates every summary.
|
|
20
|
+
* A routing answer is keyed by the exact prompt, which already holds the question and every node it was shown.
|
|
21
|
+
* Only answers that parsed are stored (as in the evidence cache, a malformed response is never cached), so a
|
|
22
|
+
* replay is always a usable answer.
|
|
23
|
+
*
|
|
24
|
+
* Design follows src/evidence/evidenceCache.ts: SQLite + WAL + busy_timeout=10000 + INSERT OR IGNORE.
|
|
25
|
+
*/
|
|
26
|
+
exports.ROUTER_CACHE_SCHEMA_VERSION = 'session-router-v1';
|
|
27
|
+
const sha256 = (text) => node_crypto_1.default.createHash('sha256').update(text).digest('hex');
|
|
28
|
+
class RouterCache {
|
|
29
|
+
db;
|
|
30
|
+
getSummaryStmt;
|
|
31
|
+
putSummaryStmt;
|
|
32
|
+
getRouteStmt;
|
|
33
|
+
putRouteStmt;
|
|
34
|
+
touchRouteStmt;
|
|
35
|
+
constructor(dbPath) {
|
|
36
|
+
node_fs_1.default.mkdirSync(node_path_1.default.dirname(dbPath), { recursive: true });
|
|
37
|
+
this.db = new better_sqlite3_1.default(dbPath);
|
|
38
|
+
this.db.pragma('journal_mode = WAL');
|
|
39
|
+
this.db.pragma('busy_timeout = 10000');
|
|
40
|
+
this.db.exec(`
|
|
41
|
+
CREATE TABLE IF NOT EXISTS note_summaries (
|
|
42
|
+
cache_key TEXT PRIMARY KEY,
|
|
43
|
+
schema_version TEXT NOT NULL,
|
|
44
|
+
model TEXT NOT NULL,
|
|
45
|
+
note_hash TEXT NOT NULL,
|
|
46
|
+
title TEXT NOT NULL,
|
|
47
|
+
summary TEXT NOT NULL,
|
|
48
|
+
created_at TEXT NOT NULL
|
|
49
|
+
);
|
|
50
|
+
CREATE TABLE IF NOT EXISTS router_answers (
|
|
51
|
+
cache_key TEXT PRIMARY KEY,
|
|
52
|
+
schema_version TEXT NOT NULL,
|
|
53
|
+
model TEXT NOT NULL,
|
|
54
|
+
node_ids_json TEXT NOT NULL,
|
|
55
|
+
thinking TEXT NOT NULL,
|
|
56
|
+
prompt_tokens INTEGER NOT NULL DEFAULT 0,
|
|
57
|
+
completion_tokens INTEGER NOT NULL DEFAULT 0,
|
|
58
|
+
latency_ms INTEGER NOT NULL DEFAULT 0,
|
|
59
|
+
created_at TEXT NOT NULL,
|
|
60
|
+
hits INTEGER NOT NULL DEFAULT 0
|
|
61
|
+
);
|
|
62
|
+
`);
|
|
63
|
+
this.getSummaryStmt = this.db.prepare('SELECT title, summary, model FROM note_summaries WHERE cache_key = ?');
|
|
64
|
+
this.putSummaryStmt = this.db.prepare(`INSERT OR IGNORE INTO note_summaries (cache_key, schema_version, model, note_hash, title, summary, created_at)
|
|
65
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`);
|
|
66
|
+
this.getRouteStmt = this.db.prepare('SELECT node_ids_json, thinking, model, prompt_tokens, completion_tokens, latency_ms FROM router_answers WHERE cache_key = ?');
|
|
67
|
+
this.putRouteStmt = this.db.prepare(`INSERT OR IGNORE INTO router_answers
|
|
68
|
+
(cache_key, schema_version, model, node_ids_json, thinking, prompt_tokens, completion_tokens, latency_ms, created_at, hits)
|
|
69
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 0)`);
|
|
70
|
+
this.touchRouteStmt = this.db.prepare('UPDATE router_answers SET hits = hits + 1 WHERE cache_key = ?');
|
|
71
|
+
}
|
|
72
|
+
static summaryKey(model, promptTemplate, noteHash) {
|
|
73
|
+
return sha256(`${exports.ROUTER_CACHE_SCHEMA_VERSION}\0summary\0${model}\0${sha256(promptTemplate)}\0${noteHash}`);
|
|
74
|
+
}
|
|
75
|
+
static routeKey(model, prompt) {
|
|
76
|
+
return sha256(`${exports.ROUTER_CACHE_SCHEMA_VERSION}\0route\0${model}\0${prompt}`);
|
|
77
|
+
}
|
|
78
|
+
getSummary(key) {
|
|
79
|
+
const row = this.getSummaryStmt.get(key);
|
|
80
|
+
return row ?? null;
|
|
81
|
+
}
|
|
82
|
+
putSummary(key, noteHash, entry) {
|
|
83
|
+
this.putSummaryStmt.run(key, exports.ROUTER_CACHE_SCHEMA_VERSION, entry.model, noteHash, entry.title, entry.summary, new Date().toISOString());
|
|
84
|
+
}
|
|
85
|
+
getRoute(key) {
|
|
86
|
+
const row = this.getRouteStmt.get(key);
|
|
87
|
+
if (!row)
|
|
88
|
+
return null;
|
|
89
|
+
this.touchRouteStmt.run(key);
|
|
90
|
+
return {
|
|
91
|
+
nodeIds: JSON.parse(row.node_ids_json),
|
|
92
|
+
thinking: row.thinking,
|
|
93
|
+
model: row.model,
|
|
94
|
+
promptTokens: row.prompt_tokens,
|
|
95
|
+
completionTokens: row.completion_tokens,
|
|
96
|
+
latencyMs: row.latency_ms,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
putRoute(key, entry) {
|
|
100
|
+
this.putRouteStmt.run(key, exports.ROUTER_CACHE_SCHEMA_VERSION, entry.model, JSON.stringify(entry.nodeIds), entry.thinking, entry.promptTokens, entry.completionTokens, entry.latencyMs, new Date().toISOString());
|
|
101
|
+
}
|
|
102
|
+
close() {
|
|
103
|
+
this.db.close();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.RouterCache = RouterCache;
|