@cerefox/memory 1.0.4 → 1.0.6
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/bin/cerefox.js +60 -43
- package/dist/frontend/assets/{index-Csj-6UHY.js → index-VeqA60-v.js} +2 -2
- package/dist/frontend/assets/{index-Csj-6UHY.js.map → index-VeqA60-v.js.map} +1 -1
- package/dist/frontend/index.html +1 -1
- package/dist/server-assets/_shared/ef-meta/index.ts +2 -2
- package/dist/server-assets/_shared/mcp-tools/_utils.ts +48 -12
- package/dist/server-assets/_shared/mcp-tools/search.ts +2 -2
- package/dist/server-assets/db/rpcs.sql +20 -4
- package/dist/server-assets/db/schema.sql +1 -1
- package/docs/guides/configuration.md +8 -5
- package/package.json +1 -1
package/dist/bin/cerefox.js
CHANGED
|
@@ -7184,7 +7184,7 @@ var exports_meta = {};
|
|
|
7184
7184
|
__export(exports_meta, {
|
|
7185
7185
|
PKG_VERSION: () => PKG_VERSION
|
|
7186
7186
|
});
|
|
7187
|
-
var PKG_VERSION = "1.0.
|
|
7187
|
+
var PKG_VERSION = "1.0.6";
|
|
7188
7188
|
var init_meta = () => {};
|
|
7189
7189
|
|
|
7190
7190
|
// ../../node_modules/.bun/tslib@2.8.1/node_modules/tslib/tslib.js
|
|
@@ -25217,21 +25217,35 @@ function getMaxResponseBytes() {
|
|
|
25217
25217
|
const n = Number.parseInt(raw, 10);
|
|
25218
25218
|
return Number.isNaN(n) || n <= 0 ? MAX_RESPONSE_BYTES : n;
|
|
25219
25219
|
}
|
|
25220
|
-
function
|
|
25221
|
-
const
|
|
25222
|
-
const
|
|
25223
|
-
if (
|
|
25224
|
-
return
|
|
25225
|
-
|
|
25226
|
-
|
|
25220
|
+
function readEnv(name) {
|
|
25221
|
+
const g = globalThis;
|
|
25222
|
+
const fromProcess = g.process?.env?.[name];
|
|
25223
|
+
if (fromProcess !== undefined && fromProcess !== "")
|
|
25224
|
+
return fromProcess;
|
|
25225
|
+
try {
|
|
25226
|
+
const fromDeno = g.Deno?.env?.get(name);
|
|
25227
|
+
return fromDeno === "" ? undefined : fromDeno;
|
|
25228
|
+
} catch {
|
|
25229
|
+
return;
|
|
25230
|
+
}
|
|
25227
25231
|
}
|
|
25228
|
-
function
|
|
25229
|
-
const raw =
|
|
25230
|
-
if (raw === undefined
|
|
25232
|
+
function readUnitInterval(name) {
|
|
25233
|
+
const raw = readEnv(name);
|
|
25234
|
+
if (raw === undefined)
|
|
25231
25235
|
return;
|
|
25232
25236
|
const n = Number.parseFloat(raw);
|
|
25233
25237
|
return Number.isNaN(n) || n < 0 || n > 1 ? undefined : n;
|
|
25234
25238
|
}
|
|
25239
|
+
function getSearchAlpha() {
|
|
25240
|
+
return readUnitInterval("CEREFOX_SEARCH_ALPHA") ?? DEFAULT_SEARCH_ALPHA;
|
|
25241
|
+
}
|
|
25242
|
+
function getMinSearchScore() {
|
|
25243
|
+
const fallback = readEnv("CEREFOX_EMBEDDER") === "local" ? DEFAULT_MIN_SEARCH_SCORE_LOCAL : DEFAULT_MIN_SEARCH_SCORE;
|
|
25244
|
+
return readUnitInterval("CEREFOX_MIN_SEARCH_SCORE") ?? fallback;
|
|
25245
|
+
}
|
|
25246
|
+
function getMinTermCoverage() {
|
|
25247
|
+
return readUnitInterval("CEREFOX_MIN_TERM_COVERAGE");
|
|
25248
|
+
}
|
|
25235
25249
|
function applyByteBudget(rows, maxBytes) {
|
|
25236
25250
|
const accepted = [];
|
|
25237
25251
|
let usedBytes = 0;
|
|
@@ -25259,7 +25273,7 @@ function logUsage(supabase, params) {
|
|
|
25259
25273
|
p_extra: params.extra ?? {}
|
|
25260
25274
|
})).catch(() => {});
|
|
25261
25275
|
}
|
|
25262
|
-
var MAX_RESPONSE_BYTES = 200000, DEFAULT_MIN_SEARCH_SCORE = 0.5, DEFAULT_MIN_SEARCH_SCORE_LOCAL = 0.6;
|
|
25276
|
+
var MAX_RESPONSE_BYTES = 200000, DEFAULT_MIN_SEARCH_SCORE = 0.5, DEFAULT_MIN_SEARCH_SCORE_LOCAL = 0.6, DEFAULT_SEARCH_ALPHA = 0.7;
|
|
25263
25277
|
|
|
25264
25278
|
// ../../_shared/mcp-tools/_projects.ts
|
|
25265
25279
|
async function ensureDocumentInProject(supabase, documentId, projectName) {
|
|
@@ -55577,7 +55591,7 @@ async function handler9(supabase, args, ctx) {
|
|
|
55577
55591
|
const project_name = args.project_name;
|
|
55578
55592
|
const match_count = args.match_count ?? 5;
|
|
55579
55593
|
const mode = args.mode ?? "docs";
|
|
55580
|
-
const alpha = args.alpha ??
|
|
55594
|
+
const alpha = args.alpha ?? getSearchAlpha();
|
|
55581
55595
|
const min_score = args.min_score ?? getMinSearchScore();
|
|
55582
55596
|
const min_term_coverage = args.min_term_coverage ?? getMinTermCoverage();
|
|
55583
55597
|
const coverageParam = min_term_coverage !== undefined ? { p_min_term_coverage: min_term_coverage } : {};
|
|
@@ -69069,16 +69083,22 @@ import { join as join2, resolve } from "node:path";
|
|
|
69069
69083
|
async function fetchAllPages(makeQuery, batchSize = 200) {
|
|
69070
69084
|
const results = [];
|
|
69071
69085
|
let offset = 0;
|
|
69086
|
+
let serverTotal = null;
|
|
69072
69087
|
for (;; ) {
|
|
69073
|
-
const { data, error } = await makeQuery(offset, offset + batchSize - 1);
|
|
69088
|
+
const { data, error, count } = await makeQuery(offset, offset + batchSize - 1);
|
|
69074
69089
|
if (error)
|
|
69075
69090
|
throw new Error(error.message ?? JSON.stringify(error));
|
|
69091
|
+
if (typeof count === "number")
|
|
69092
|
+
serverTotal = count;
|
|
69076
69093
|
const page = data ?? [];
|
|
69077
69094
|
results.push(...page);
|
|
69078
69095
|
if (page.length < batchSize)
|
|
69079
69096
|
break;
|
|
69080
69097
|
offset += batchSize;
|
|
69081
69098
|
}
|
|
69099
|
+
if (serverTotal !== null && results.length !== serverTotal) {
|
|
69100
|
+
throw new Error(`Paginated read returned ${results.length} row(s) but the server reports ` + `${serverTotal}. Refusing to return a partial result — retry, and if this ` + `persists please report it (the rows may be changing under the read).`);
|
|
69101
|
+
}
|
|
69082
69102
|
return results;
|
|
69083
69103
|
}
|
|
69084
69104
|
|
|
@@ -75000,8 +75020,8 @@ import { homedir as homedir6 } from "node:os";
|
|
|
75000
75020
|
import { join as join9 } from "node:path";
|
|
75001
75021
|
|
|
75002
75022
|
// ../../_shared/ef-meta/index.ts
|
|
75003
|
-
var EF_VERSION = "1.0.
|
|
75004
|
-
var EF_LAST_CHANGED = "1.0.
|
|
75023
|
+
var EF_VERSION = "1.0.6";
|
|
75024
|
+
var EF_LAST_CHANGED = "1.0.6";
|
|
75005
75025
|
|
|
75006
75026
|
// src/cli/util/checks.ts
|
|
75007
75027
|
init_config();
|
|
@@ -75527,9 +75547,9 @@ async function checkEdgeFunctionsCompat() {
|
|
|
75527
75547
|
}
|
|
75528
75548
|
return {
|
|
75529
75549
|
name: "edge functions",
|
|
75530
|
-
status: "
|
|
75531
|
-
detail: `Deployed Edge Functions (v${deployed}) are older than
|
|
75532
|
-
hint: "
|
|
75550
|
+
status: "warn",
|
|
75551
|
+
detail: `Deployed Edge Functions (v${deployed}) are older than this client's bundled v${EF_VERSION} and predate server-side fixes shipped in v${EF_LAST_CHANGED}. Still compatible, but you are missing those fixes.`,
|
|
75552
|
+
hint: "Update the Edge Functions (see remediation below)."
|
|
75533
75553
|
};
|
|
75534
75554
|
default:
|
|
75535
75555
|
return {
|
|
@@ -75628,11 +75648,11 @@ async function action15(options) {
|
|
|
75628
75648
|
const needsEf = stale("edge functions");
|
|
75629
75649
|
let remediation = null;
|
|
75630
75650
|
if (needsSchema && needsEf) {
|
|
75631
|
-
remediation = "
|
|
75651
|
+
remediation = "This release needs a server update (schema + RPCs + Edge Functions): cerefox server deploy";
|
|
75632
75652
|
} else if (needsSchema) {
|
|
75633
|
-
remediation = "
|
|
75653
|
+
remediation = "This release needs a schema + RPC update: cerefox server deploy --schema-only";
|
|
75634
75654
|
} else if (needsEf) {
|
|
75635
|
-
remediation = "
|
|
75655
|
+
remediation = "This release needs an Edge Function update: cerefox server deploy --functions-only";
|
|
75636
75656
|
}
|
|
75637
75657
|
if (remediation) {
|
|
75638
75658
|
println(cErr.yellow("→ " + remediation));
|
|
@@ -75859,7 +75879,7 @@ class IngestionDbBridge {
|
|
|
75859
75879
|
return rows.length > 0 ? rows[0] : null;
|
|
75860
75880
|
}
|
|
75861
75881
|
async listChunksForDocument(documentId) {
|
|
75862
|
-
const
|
|
75882
|
+
const data = await fetchAllPages((from, to) => this.supabase.from("cerefox_chunks").select("id, document_id, chunk_index, heading_path, heading_level, title, content, char_count").eq("document_id", documentId).is("version_id", null).order("chunk_index").range(from, to));
|
|
75863
75883
|
return data ?? [];
|
|
75864
75884
|
}
|
|
75865
75885
|
async getDocumentProjectIds(documentId) {
|
|
@@ -77474,7 +77494,7 @@ async function action29(query, options) {
|
|
|
77474
77494
|
throw userError("Empty query.");
|
|
77475
77495
|
}
|
|
77476
77496
|
const matchCount = parsePositiveInt(options.matchCount, "--match-count", 5);
|
|
77477
|
-
const alpha = parseFloat01(options.alpha, "--alpha",
|
|
77497
|
+
const alpha = parseFloat01(options.alpha, "--alpha", getSearchAlpha());
|
|
77478
77498
|
const minScore = parseFloat01(options.minScore, "--min-score", getMinSearchScore());
|
|
77479
77499
|
const envCoverage = getMinTermCoverage();
|
|
77480
77500
|
const coverageParam = options.minTermCoverage !== undefined ? { p_min_term_coverage: parseFloat01(options.minTermCoverage, "--min-term-coverage", envCoverage ?? 0.5) } : envCoverage !== undefined ? { p_min_term_coverage: envCoverage } : {};
|
|
@@ -77633,7 +77653,7 @@ async function action29(query, options) {
|
|
|
77633
77653
|
}
|
|
77634
77654
|
}
|
|
77635
77655
|
function registerSearch(program2) {
|
|
77636
|
-
program2.command("search").description("Search the knowledge base (hybrid FTS + semantic).").argument("<query>", "Natural-language search query.").option("-c, --match-count <n>", "Maximum number of documents to return.", "5").option("-p, --project-name <name>", "Filter results to a specific project.").option("-f, --metadata-filter <json>", "JSON containment filter; only docs whose metadata contains ALL pairs are returned.").option("--mode <mode>", "Search mode: docs (default), hybrid, fts.", "docs").option("--alpha <float>", "Semantic weight 0..1 (default: 0.7)."
|
|
77656
|
+
program2.command("search").description("Search the knowledge base (hybrid FTS + semantic).").argument("<query>", "Natural-language search query.").option("-c, --match-count <n>", "Maximum number of documents to return.", "5").option("-p, --project-name <name>", "Filter results to a specific project.").option("-f, --metadata-filter <json>", "JSON containment filter; only docs whose metadata contains ALL pairs are returned.").option("--mode <mode>", "Search mode: docs (default), hybrid, fts.", "docs").option("--alpha <float>", "Semantic weight 0..1 (default: CEREFOX_SEARCH_ALPHA; else 0.7).").option("--min-score <float>", "Minimum cosine similarity threshold (default: CEREFOX_MIN_SEARCH_SCORE; else 0.5, or 0.6 with the local embedder).").option("--min-term-coverage <float>", "OR-fallback keyword matches must cover at least this fraction of the query's meaningful terms to count as confident hits (default: CEREFOX_MIN_TERM_COVERAGE; else the server default 0.5; needs schema ≥ 0.9.1).").option("--max-bytes <n>", "Response size budget in bytes (default: CEREFOX_MAX_RESPONSE_BYTES or 200000).").option("-r, --requestor <name>", "Agent / user name (recorded in usage log).").option("--json", "Emit machine-readable JSON instead of the default text.").option("--only-metadata", "List matching docs (id, score, chunks, chars, partial/full) WITHOUT their content — like the web UI's collapsed result list. Grab a [id:…] then `cerefox document get <id>`.").action(action29);
|
|
77637
77657
|
}
|
|
77638
77658
|
|
|
77639
77659
|
// src/cli/commands/self-update.ts
|
|
@@ -81451,23 +81471,18 @@ function parseMetadataFilter(raw2) {
|
|
|
81451
81471
|
}
|
|
81452
81472
|
async function listDocuments(ctx, opts) {
|
|
81453
81473
|
const { projectId, limit, offset = 0 } = opts;
|
|
81454
|
-
|
|
81455
|
-
|
|
81456
|
-
|
|
81457
|
-
|
|
81458
|
-
throw error4;
|
|
81459
|
-
docIds = (data2 ?? []).map((r) => r.document_id);
|
|
81460
|
-
if (docIds.length === 0)
|
|
81461
|
-
return [];
|
|
81462
|
-
}
|
|
81463
|
-
let q = ctx.supabase.from("cerefox_documents").select(DOC_COLS).is("deleted_at", null).order("updated_at", { ascending: false });
|
|
81464
|
-
if (docIds)
|
|
81465
|
-
q = q.in("id", docIds);
|
|
81474
|
+
const selectCols = projectId ? `${DOC_COLS}, cerefox_document_projects!inner(project_id)` : DOC_COLS;
|
|
81475
|
+
let q = ctx.supabase.from("cerefox_documents").select(selectCols).is("deleted_at", null).order("updated_at", { ascending: false });
|
|
81476
|
+
if (projectId)
|
|
81477
|
+
q = q.eq("cerefox_document_projects.project_id", projectId);
|
|
81466
81478
|
q = q.range(offset, offset + limit - 1);
|
|
81467
81479
|
const { data, error: error3 } = await q;
|
|
81468
81480
|
if (error3)
|
|
81469
81481
|
throw error3;
|
|
81470
|
-
return data ?? []
|
|
81482
|
+
return (data ?? []).map((row) => {
|
|
81483
|
+
const { cerefox_document_projects: _j, ...doc2 } = row;
|
|
81484
|
+
return doc2;
|
|
81485
|
+
});
|
|
81471
81486
|
}
|
|
81472
81487
|
async function listAllProjects(ctx) {
|
|
81473
81488
|
const { data, error: error3 } = await ctx.supabase.from("cerefox_projects").select("*").order("name");
|
|
@@ -81583,7 +81598,8 @@ function projectDocResult(r) {
|
|
|
81583
81598
|
chunk_count: r.chunk_count ?? 0,
|
|
81584
81599
|
total_chars: r.total_chars ?? 0,
|
|
81585
81600
|
doc_updated_at: r.doc_updated_at ?? null,
|
|
81586
|
-
is_partial: r.is_partial ?? false
|
|
81601
|
+
is_partial: r.is_partial ?? false,
|
|
81602
|
+
below_confidence: r.below_confidence ?? false
|
|
81587
81603
|
};
|
|
81588
81604
|
}
|
|
81589
81605
|
function projectChunkResult(r) {
|
|
@@ -81599,7 +81615,8 @@ function projectChunkResult(r) {
|
|
|
81599
81615
|
doc_title: r.doc_title ?? "",
|
|
81600
81616
|
doc_source: r.doc_source ?? null,
|
|
81601
81617
|
doc_project_ids: r.doc_project_ids ?? [],
|
|
81602
|
-
doc_metadata: r.doc_metadata ?? {}
|
|
81618
|
+
doc_metadata: r.doc_metadata ?? {},
|
|
81619
|
+
below_confidence: r.below_confidence ?? false
|
|
81603
81620
|
};
|
|
81604
81621
|
}
|
|
81605
81622
|
async function runSearch(ctx, opts) {
|
|
@@ -81640,7 +81657,7 @@ async function runSearch(ctx, opts) {
|
|
|
81640
81657
|
p_query_text: query,
|
|
81641
81658
|
p_query_embedding: embedding,
|
|
81642
81659
|
p_match_count: count,
|
|
81643
|
-
p_alpha:
|
|
81660
|
+
p_alpha: getSearchAlpha(),
|
|
81644
81661
|
p_use_upgrade: false,
|
|
81645
81662
|
p_project_id: projectId,
|
|
81646
81663
|
p_min_score: getMinSearchScore()
|
|
@@ -81656,7 +81673,7 @@ async function runSearch(ctx, opts) {
|
|
|
81656
81673
|
p_query_text: query,
|
|
81657
81674
|
p_query_embedding: embedding,
|
|
81658
81675
|
p_match_count: Math.min(count, 5),
|
|
81659
|
-
p_alpha:
|
|
81676
|
+
p_alpha: getSearchAlpha(),
|
|
81660
81677
|
p_project_id: projectId,
|
|
81661
81678
|
p_min_score: getMinSearchScore()
|
|
81662
81679
|
};
|
|
@@ -82079,7 +82096,7 @@ function registerDocumentReadRoutes(app, ctx) {
|
|
|
82079
82096
|
});
|
|
82080
82097
|
app.get("/api/v1/documents/:document_id/chunks", async (c2) => {
|
|
82081
82098
|
const documentId = c2.req.param("document_id");
|
|
82082
|
-
const { data, error: error3 } = await ctx.supabase.from("cerefox_chunks").select("id, document_id, chunk_index, heading_path, heading_level, title, content, char_count").eq("document_id", documentId).is("version_id", null).order("chunk_index");
|
|
82099
|
+
const { data, error: error3 } = await ctx.supabase.from("cerefox_chunks").select("id, document_id, chunk_index, heading_path, heading_level, title, content, char_count").eq("document_id", documentId).is("version_id", null).order("chunk_index").range(0, 4999);
|
|
82083
82100
|
if (error3)
|
|
82084
82101
|
return c2.json({ detail: error3.message }, 500);
|
|
82085
82102
|
const rows = data ?? [];
|