lancedb-opencode-pro 0.1.4 → 0.1.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.
package/README.md CHANGED
@@ -272,7 +272,7 @@ Example output:
272
272
  ```json
273
273
  {
274
274
  "scope": "project:my-project",
275
- "totalEvents": 12,
275
+ "totalEvents": 14,
276
276
  "capture": {
277
277
  "considered": 4,
278
278
  "stored": 3,
@@ -283,11 +283,24 @@ Example output:
283
283
  }
284
284
  },
285
285
  "recall": {
286
- "requested": 3,
286
+ "requested": 4,
287
287
  "injected": 2,
288
- "returnedResults": 2,
289
- "hitRate": 0.67,
290
- "injectionRate": 0.67
288
+ "returnedResults": 3,
289
+ "hitRate": 0.75,
290
+ "injectionRate": 0.5,
291
+ "auto": {
292
+ "requested": 3,
293
+ "injected": 2,
294
+ "returnedResults": 2,
295
+ "hitRate": 0.67,
296
+ "injectionRate": 0.67
297
+ },
298
+ "manual": {
299
+ "requested": 1,
300
+ "returnedResults": 1,
301
+ "hitRate": 1
302
+ },
303
+ "manualRescueRatio": 0.33
291
304
  },
292
305
  "feedback": {
293
306
  "missing": 1,
@@ -306,7 +319,10 @@ Example output:
306
319
  Key fields:
307
320
 
308
321
  - `capture.successRate`: how often a considered candidate was stored.
309
- - `recall.hitRate`: how often a recall request returned at least one result.
322
+ - `recall.hitRate`: blended rate across auto and manual recall — how often any recall request returned at least one result.
323
+ - `recall.auto.*`: metrics for automatic recall injected into the system prompt during `experimental.chat.system.transform`.
324
+ - `recall.manual.*`: metrics for user-initiated `memory_search` calls; `injected` is always false for manual searches.
325
+ - `recall.manualRescueRatio`: `manual.requested / auto.requested` — a proxy for how often users still need to search manually despite automatic recall.
310
326
  - `feedback.falsePositiveRate`: wrong-memory reports divided by stored memories.
311
327
  - `feedback.falseNegativeRate`: missing-memory reports relative to capture attempts.
312
328
 
@@ -315,6 +331,8 @@ Key fields:
315
331
  In real OpenCode usage, auto-capture and recall happen in the background, so explicit `memory_feedback_*` events are often sparse.
316
332
 
317
333
  - Treat `capture.*` and `recall.*` as system-health metrics: they show whether the memory pipeline is running.
334
+ - Treat `recall.auto.*` and `recall.manual.*` separately: auto metrics reflect pipeline health; manual metrics reflect whether users still need to rescue context manually.
335
+ - Treat `recall.manualRescueRatio` as a proxy for manual rescue rate: a high ratio suggests automatic recall is not surfacing relevant context on its own.
318
336
  - Treat repeated-context reduction, clarification burden, manual memory rescue, correction signals, and sampled audits as product-value signals: they show whether memory actually helped the user.
319
337
  - Treat `feedback.* = 0` as insufficient evidence, not proof that memory quality is good.
320
338
  - Treat a high `recall.hitRate` or `recall.injectionRate` as recall availability only; those values do not prove usefulness by themselves.
package/dist/index.js CHANGED
@@ -64,6 +64,7 @@ const plugin = async (input) => {
64
64
  await state.store.putEvent({
65
65
  id: generateId(),
66
66
  type: "recall",
67
+ source: "system-transform",
67
68
  scope: activeScope,
68
69
  sessionID: eventInput.sessionID,
69
70
  timestamp: Date.now(),
@@ -117,6 +118,17 @@ const plugin = async (input) => {
117
118
  recencyHalfLifeHours: state.config.retrieval.recencyHalfLifeHours,
118
119
  importanceWeight: state.config.retrieval.importanceWeight,
119
120
  });
121
+ await state.store.putEvent({
122
+ id: generateId(),
123
+ type: "recall",
124
+ source: "manual-search",
125
+ scope: activeScope,
126
+ sessionID: context.sessionID,
127
+ timestamp: Date.now(),
128
+ resultCount: results.length,
129
+ injected: false,
130
+ metadataJson: JSON.stringify({ source: "manual-search" }),
131
+ });
120
132
  if (results.length === 0)
121
133
  return "No relevant memory found.";
122
134
  return results
package/dist/store.js CHANGED
@@ -59,6 +59,7 @@ export class MemoryStore {
59
59
  skipReason: "",
60
60
  resultCount: 0,
61
61
  injected: false,
62
+ source: "",
62
63
  feedbackType: "",
63
64
  helpful: -1,
64
65
  reason: "",
@@ -89,6 +90,7 @@ export class MemoryStore {
89
90
  skipReason: event.type === "capture" ? event.skipReason ?? "" : "",
90
91
  resultCount: event.type === "recall" ? event.resultCount : 0,
91
92
  injected: event.type === "recall" ? event.injected : false,
93
+ source: event.type === "recall" ? event.source ?? "" : "",
92
94
  feedbackType: event.type === "feedback" ? event.feedbackType : "",
93
95
  helpful: event.type === "feedback" ? (event.helpful === undefined ? -1 : event.helpful ? 1 : 0) : -1,
94
96
  reason: event.type === "feedback" ? event.reason ?? "" : "",
@@ -207,6 +209,11 @@ export class MemoryStore {
207
209
  let recallRequested = 0;
208
210
  let recallInjected = 0;
209
211
  let recallReturnedResults = 0;
212
+ let autoRecallRequested = 0;
213
+ let autoRecallInjected = 0;
214
+ let autoRecallReturnedResults = 0;
215
+ let manualRecallRequested = 0;
216
+ let manualRecallReturnedResults = 0;
210
217
  let feedbackMissing = 0;
211
218
  let feedbackWrong = 0;
212
219
  let feedbackUsefulPositive = 0;
@@ -230,6 +237,19 @@ export class MemoryStore {
230
237
  recallReturnedResults += 1;
231
238
  if (event.injected)
232
239
  recallInjected += 1;
240
+ const recallSource = event.source ?? "system-transform";
241
+ if (recallSource === "manual-search") {
242
+ manualRecallRequested += 1;
243
+ if (event.resultCount > 0)
244
+ manualRecallReturnedResults += 1;
245
+ }
246
+ else {
247
+ autoRecallRequested += 1;
248
+ if (event.resultCount > 0)
249
+ autoRecallReturnedResults += 1;
250
+ if (event.injected)
251
+ autoRecallInjected += 1;
252
+ }
233
253
  }
234
254
  if (event.type === "feedback") {
235
255
  if (event.feedbackType === "missing")
@@ -262,6 +282,19 @@ export class MemoryStore {
262
282
  returnedResults: recallReturnedResults,
263
283
  hitRate: recallRequested === 0 ? 0 : recallReturnedResults / recallRequested,
264
284
  injectionRate: recallRequested === 0 ? 0 : recallInjected / recallRequested,
285
+ auto: {
286
+ requested: autoRecallRequested,
287
+ injected: autoRecallInjected,
288
+ returnedResults: autoRecallReturnedResults,
289
+ hitRate: autoRecallRequested === 0 ? 0 : autoRecallReturnedResults / autoRecallRequested,
290
+ injectionRate: autoRecallRequested === 0 ? 0 : autoRecallInjected / autoRecallRequested,
291
+ },
292
+ manual: {
293
+ requested: manualRecallRequested,
294
+ returnedResults: manualRecallReturnedResults,
295
+ hitRate: manualRecallRequested === 0 ? 0 : manualRecallReturnedResults / manualRecallRequested,
296
+ },
297
+ manualRescueRatio: autoRecallRequested === 0 ? 0 : manualRecallRequested / autoRecallRequested,
265
298
  },
266
299
  feedback: {
267
300
  missing: feedbackMissing,
@@ -346,6 +379,7 @@ export class MemoryStore {
346
379
  "skipReason",
347
380
  "resultCount",
348
381
  "injected",
382
+ "source",
349
383
  "feedbackType",
350
384
  "helpful",
351
385
  "reason",
@@ -456,11 +490,14 @@ function normalizeEventRow(row) {
456
490
  };
457
491
  }
458
492
  if (row.type === "recall") {
493
+ const sourceRaw = typeof row.source === "string" && row.source.length > 0 ? row.source : "system-transform";
494
+ const source = sourceRaw === "manual-search" ? "manual-search" : "system-transform";
459
495
  return {
460
496
  ...base,
461
497
  type: "recall",
462
498
  resultCount: Number(row.resultCount ?? 0),
463
499
  injected: Boolean(row.injected),
500
+ source,
464
501
  };
465
502
  }
466
503
  if (row.type === "feedback") {
package/dist/types.d.ts CHANGED
@@ -4,6 +4,7 @@ export type MemoryCategory = "preference" | "fact" | "decision" | "entity" | "ot
4
4
  export type CaptureOutcome = "considered" | "skipped" | "stored";
5
5
  export type CaptureSkipReason = "empty-buffer" | "below-min-chars" | "no-positive-signal" | "initialization-unavailable" | "embedding-unavailable" | "empty-embedding";
6
6
  export type FeedbackType = "missing" | "wrong" | "useful";
7
+ export type RecallSource = "system-transform" | "manual-search";
7
8
  export interface EmbeddingConfig {
8
9
  provider: EmbeddingProvider;
9
10
  model: string;
@@ -76,6 +77,7 @@ export interface RecallEvent extends MemoryEffectivenessEventBase {
76
77
  type: "recall";
77
78
  resultCount: number;
78
79
  injected: boolean;
80
+ source?: RecallSource;
79
81
  }
80
82
  export interface FeedbackEvent extends MemoryEffectivenessEventBase {
81
83
  type: "feedback";
@@ -101,6 +103,19 @@ export interface EffectivenessSummary {
101
103
  returnedResults: number;
102
104
  hitRate: number;
103
105
  injectionRate: number;
106
+ auto: {
107
+ requested: number;
108
+ injected: number;
109
+ returnedResults: number;
110
+ hitRate: number;
111
+ injectionRate: number;
112
+ };
113
+ manual: {
114
+ requested: number;
115
+ returnedResults: number;
116
+ hitRate: number;
117
+ };
118
+ manualRescueRatio: number;
104
119
  };
105
120
  feedback: {
106
121
  missing: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lancedb-opencode-pro",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "LanceDB-backed long-term memory provider for OpenCode",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -63,5 +63,10 @@
63
63
  "devDependencies": {
64
64
  "@types/node": "^22.13.9",
65
65
  "typescript": "^5.8.2"
66
- }
66
+ },
67
+ "directories": {
68
+ "doc": "docs",
69
+ "test": "test"
70
+ },
71
+ "author": ""
67
72
  }