botnote 0.2.4 → 0.2.5

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.
@@ -14,8 +14,10 @@ export interface SearchHit {
14
14
  /** True when another entity supersedes this one (score multiplied down). */
15
15
  superseded?: boolean;
16
16
  }
17
+ export declare function timeDecayFor(createdAt: Date, now?: Date): number;
17
18
  export declare function search(scope: Scope, db: Database["db"], input: SearchInput, opts?: {
18
19
  queryEmbedding?: number[];
20
+ now?: Date;
19
21
  }): Promise<SearchHit[]>;
20
22
  /**
21
23
  * Near-duplicate candidates for a freshly written note, used by `remember`
@@ -17,11 +17,77 @@ const KIND_WEIGHTS = {
17
17
  feedback: -0.1,
18
18
  log: -0.2
19
19
  };
20
+ // Freshness is a tie-breaker, not a relevance signal: the boost decays with
21
+ // the hit's own age and its maximum stays below the RRF gap between rank 1
22
+ // and rank 2 (1/61 - 1/62 ≈ 2.6e-4), so it can never lift a hit over one
23
+ // ranked above it in any modality.
24
+ const TIME_DECAY_MAX = 0.00025;
25
+ const TIME_DECAY_SCALE_DAYS = 90;
26
+ const DAY_MS = 86_400_000;
27
+ export function timeDecayFor(createdAt, now = new Date()) {
28
+ const ageDays = Math.max(0, (now.getTime() - createdAt.getTime()) / DAY_MS);
29
+ return TIME_DECAY_MAX * Math.exp(-ageDays / TIME_DECAY_SCALE_DAYS);
30
+ }
20
31
  function rrfScore(rank) {
21
32
  if (rank == null)
22
33
  return 0;
23
34
  return 1 / (RRF_K + rank);
24
35
  }
36
+ /** Rows arrive in the sub-query's ORDER BY; position is the modality rank. */
37
+ function rankMap(rows) {
38
+ const m = new Map();
39
+ rows.forEach((r, i) => m.set(r.id, i + 1));
40
+ return m;
41
+ }
42
+ // HNSW evaluates the WHERE clause after the nearest-neighbour walk, so the
43
+ // default ef_search=40 can leave a project-scoped query with almost nothing.
44
+ // Widen the candidate set per query (ef_search caps at 1000) and, where
45
+ // pgvector supports it, keep scanning until LIMIT rows pass the filter.
46
+ const HNSW_EF_SEARCH_MIN = 200;
47
+ const HNSW_EF_SEARCH_MAX = 1000;
48
+ const iterativeScanSupport = new WeakMap();
49
+ function versionAtLeast(version, min) {
50
+ if (!version)
51
+ return false;
52
+ const parts = version.split(".").map((p) => Number.parseInt(p, 10) || 0);
53
+ for (let i = 0; i < 3; i++) {
54
+ const v = parts[i] ?? 0;
55
+ if (v > min[i])
56
+ return true;
57
+ if (v < min[i])
58
+ return false;
59
+ }
60
+ return true;
61
+ }
62
+ function supportsIterativeScan(db) {
63
+ let cached = iterativeScanSupport.get(db);
64
+ if (!cached) {
65
+ cached = db
66
+ .execute(sql `SELECT extversion FROM pg_extension WHERE extname = 'vector'`)
67
+ .then((r) => versionAtLeast(r.rows[0]?.extversion, [0, 8, 0]))
68
+ .catch(() => false);
69
+ iterativeScanSupport.set(db, cached);
70
+ }
71
+ return cached;
72
+ }
73
+ async function nearestRows(db, queryEmbedding, commonFilter, fetchN) {
74
+ const vecLiteral = `[${queryEmbedding.join(",")}]`;
75
+ const efSearch = Math.min(HNSW_EF_SEARCH_MAX, Math.max(HNSW_EF_SEARCH_MIN, fetchN * 4));
76
+ const iterative = await supportsIterativeScan(db);
77
+ return db.transaction(async (tx) => {
78
+ await tx.execute(sql.raw(`SET LOCAL hnsw.ef_search = ${efSearch}`));
79
+ if (iterative)
80
+ await tx.execute(sql `SET LOCAL hnsw.iterative_scan = relaxed_order`);
81
+ const result = await tx.execute(sql `
82
+ SELECT id
83
+ FROM entities
84
+ WHERE body_vec IS NOT NULL ${commonFilter}
85
+ ORDER BY body_vec <=> ${vecLiteral}::vector
86
+ LIMIT ${fetchN}
87
+ `);
88
+ return result.rows;
89
+ });
90
+ }
25
91
  export async function search(scope, db, input, opts = {}) {
26
92
  const wsFilter = sql `AND workspace_id = ${scope.workspaceId}::uuid`;
27
93
  const projectFilter = input.projectId
@@ -37,67 +103,51 @@ export async function search(scope, db, input, opts = {}) {
37
103
  const notTrashed = sql `AND deleted_at IS NULL`;
38
104
  const commonFilter = sql `${wsFilter} ${projectFilter} ${kindFilter} ${activeProjectFilter} ${notTrashed}`;
39
105
  const fetchN = Math.max(input.limit * 4, 40);
40
- const bm25Rows = (await db.execute(sql `
41
- SELECT id, ROW_NUMBER() OVER (ORDER BY ts_rank_cd(body_tsv, q) DESC) AS rank_pos
42
- FROM entities, websearch_to_tsquery('simple', ${input.query}) q
43
- WHERE body_tsv @@ q ${commonFilter}
44
- ORDER BY ts_rank_cd(body_tsv, q) DESC
45
- LIMIT ${fetchN}
46
- `)).rows;
47
- const ilikeFallback = bm25Rows.length === 0
48
- ? (await db.execute(sql `
49
- SELECT id,
50
- ROW_NUMBER() OVER (ORDER BY created_at DESC) AS rank_pos
51
- FROM entities
52
- WHERE (title ILIKE ${`%${input.query}%`} OR body ILIKE ${`%${input.query}%`})
53
- ${commonFilter}
54
- LIMIT ${fetchN}
55
- `)).rows
56
- : [];
57
- let vecRows = [];
58
- if (opts.queryEmbedding && opts.queryEmbedding.length > 0) {
59
- const vecLiteral = `[${opts.queryEmbedding.join(",")}]`;
60
- vecRows = (await db.execute(sql `
61
- SELECT id, ROW_NUMBER() OVER (ORDER BY body_vec <=> ${vecLiteral}::vector) AS rank_pos
106
+ const lexicalRows = async () => {
107
+ const bm25 = (await db.execute(sql `
108
+ SELECT id
109
+ FROM entities, websearch_to_tsquery('simple', ${input.query}) q
110
+ WHERE body_tsv @@ q ${commonFilter}
111
+ ORDER BY ts_rank_cd(body_tsv, q) DESC
112
+ LIMIT ${fetchN}
113
+ `)).rows;
114
+ if (bm25.length > 0)
115
+ return bm25;
116
+ return (await db.execute(sql `
117
+ SELECT id
62
118
  FROM entities
63
- WHERE body_vec IS NOT NULL ${commonFilter}
64
- ORDER BY body_vec <=> ${vecLiteral}::vector
119
+ WHERE (title ILIKE ${`%${input.query}%`} OR body ILIKE ${`%${input.query}%`})
120
+ ${commonFilter}
121
+ ORDER BY created_at DESC
65
122
  LIMIT ${fetchN}
66
123
  `)).rows;
67
- }
68
- const timeRows = (await db.execute(sql `
69
- SELECT id, ROW_NUMBER() OVER (ORDER BY created_at DESC) AS rank_pos
70
- FROM entities
71
- WHERE 1=1 ${commonFilter}
72
- ORDER BY created_at DESC
73
- LIMIT ${fetchN}
74
- `)).rows;
75
- const bm25Map = new Map();
76
- for (const r of bm25Rows.length > 0 ? bm25Rows : ilikeFallback) {
77
- bm25Map.set(r.id, Number(r.rank_pos));
78
- }
79
- const vecMap = new Map();
80
- for (const r of vecRows)
81
- vecMap.set(r.id, Number(r.rank_pos));
82
- const timeMap = new Map();
83
- for (const r of timeRows)
84
- timeMap.set(r.id, Number(r.rank_pos));
124
+ };
125
+ const hasEmbedding = !!opts.queryEmbedding && opts.queryEmbedding.length > 0;
126
+ const [bm25Rows, vecRows] = await Promise.all([
127
+ lexicalRows(),
128
+ hasEmbedding ? nearestRows(db, opts.queryEmbedding, commonFilter, fetchN) : Promise.resolve([])
129
+ ]);
130
+ const bm25Map = rankMap(bm25Rows);
131
+ const vecMap = rankMap(vecRows);
85
132
  const ids = new Set([...bm25Map.keys(), ...vecMap.keys()]);
86
133
  if (ids.size === 0)
87
134
  return [];
88
135
  const idArr = [...ids];
89
- const entitiesRows = await db
90
- .select()
91
- .from(entitiesTable)
92
- .where(and(eq(entitiesTable.workspaceId, scope.workspaceId), inArray(entitiesTable.id, idArr)));
136
+ const [entitiesRows, supersededRows] = await Promise.all([
137
+ db
138
+ .select()
139
+ .from(entitiesTable)
140
+ .where(and(eq(entitiesTable.workspaceId, scope.workspaceId), inArray(entitiesTable.id, idArr))),
141
+ db
142
+ .select({ toId: edges.toId })
143
+ .from(edges)
144
+ .where(and(eq(edges.kind, "supersedes"), inArray(edges.toId, idArr)))
145
+ ]);
93
146
  const entityMap = new Map();
94
147
  for (const r of entitiesRows)
95
148
  entityMap.set(r.id, r);
96
- const supersededRows = await db
97
- .select({ toId: edges.toId })
98
- .from(edges)
99
- .where(and(eq(edges.kind, "supersedes"), inArray(edges.toId, idArr)));
100
149
  const supersededIds = new Set(supersededRows.map((r) => r.toId));
150
+ const now = opts.now ?? new Date();
101
151
  const hits = [];
102
152
  for (const id of idArr) {
103
153
  const entity = entityMap.get(id);
@@ -105,7 +155,7 @@ export async function search(scope, db, input, opts = {}) {
105
155
  continue;
106
156
  const bm25 = rrfScore(bm25Map.get(id));
107
157
  const cosine = rrfScore(vecMap.get(id));
108
- const timeDecay = rrfScore(timeMap.get(id)) * 0.3;
158
+ const timeDecay = timeDecayFor(entity.createdAt, now);
109
159
  const kindWeight = KIND_WEIGHTS[entity.kind] ?? 0;
110
160
  const accessBoost = accessBoostFor(entity.accessCount);
111
161
  const superseded = supersededIds.has(id);
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/service/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/service/search.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botnote",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "Notion for bots. Lightweight project + notes + memory store, agent-first.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.33.0",
@@ -52,7 +52,8 @@
52
52
  "typecheck": "tsc -p tsconfig.json --noEmit",
53
53
  "test": "vitest run --no-file-parallelism",
54
54
  "db:generate": "drizzle-kit generate",
55
- "db:migrate": "tsx src/db/migrate.ts"
55
+ "db:migrate": "tsx src/db/migrate.ts",
56
+ "bench:search": "tsx scripts/bench-search.ts"
56
57
  },
57
58
  "dependencies": {
58
59
  "@fastify/cookie": "^11.0.2",