@jmtrin/opencode-kevin 0.1.5 → 0.2.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.
Files changed (42) hide show
  1. package/README.md +50 -16
  2. package/dist/migrations/003_v02_signal.sql +58 -0
  3. package/dist/plugin/ContextInjector.d.ts +13 -1
  4. package/dist/plugin/ContextInjector.js +41 -15
  5. package/dist/plugin/ContextInjector.js.map +1 -1
  6. package/dist/plugin/MemoryService.d.ts +49 -2
  7. package/dist/plugin/MemoryService.js +182 -15
  8. package/dist/plugin/MemoryService.js.map +1 -1
  9. package/dist/plugin/Migrate.d.ts +4 -1
  10. package/dist/plugin/Migrate.js +28 -1
  11. package/dist/plugin/Migrate.js.map +1 -1
  12. package/dist/plugin/PatternMiner.d.ts +49 -0
  13. package/dist/plugin/PatternMiner.js +133 -0
  14. package/dist/plugin/PatternMiner.js.map +1 -0
  15. package/dist/plugin/Reflector.d.ts +29 -2
  16. package/dist/plugin/Reflector.js +90 -7
  17. package/dist/plugin/Reflector.js.map +1 -1
  18. package/dist/plugin/Retrospective.d.ts +4 -1
  19. package/dist/plugin/Retrospective.js +72 -5
  20. package/dist/plugin/Retrospective.js.map +1 -1
  21. package/dist/plugin/Store.d.ts +15 -0
  22. package/dist/plugin/Store.js +15 -0
  23. package/dist/plugin/Store.js.map +1 -1
  24. package/dist/plugin/ToolCallObserver.d.ts +4 -1
  25. package/dist/plugin/ToolCallObserver.js +39 -7
  26. package/dist/plugin/ToolCallObserver.js.map +1 -1
  27. package/dist/plugin/fingerprint.d.ts +27 -0
  28. package/dist/plugin/fingerprint.js +74 -0
  29. package/dist/plugin/fingerprint.js.map +1 -0
  30. package/dist/plugin/index.js +93 -15
  31. package/dist/plugin/index.js.map +1 -1
  32. package/dist/plugin/memory-format.d.ts +2 -0
  33. package/dist/plugin/memory-format.js +6 -3
  34. package/dist/plugin/memory-format.js.map +1 -1
  35. package/dist/plugin/metrics.d.ts +60 -0
  36. package/dist/plugin/metrics.js +159 -0
  37. package/dist/plugin/metrics.js.map +1 -0
  38. package/dist/plugin/redact.d.ts +1 -0
  39. package/dist/plugin/redact.js +7 -0
  40. package/dist/plugin/redact.js.map +1 -1
  41. package/migrations/003_v02_signal.sql +58 -0
  42. package/package.json +48 -48
@@ -1,4 +1,16 @@
1
+ import { fingerprint as computeFingerprint } from "./fingerprint.js";
1
2
  import { uuidv7 } from "./uuid.js";
3
+ const MAX_SNIPPET_CHARS = 200;
4
+ function toSlim(mem) {
5
+ const rawScore = mem.metadata?.score;
6
+ return {
7
+ id: mem.id,
8
+ type: mem.type,
9
+ scope: mem.scope,
10
+ score: typeof rawScore === "number" ? rawScore : mem.relevanceScore,
11
+ snippet: mem.content.slice(0, MAX_SNIPPET_CHARS),
12
+ };
13
+ }
2
14
  const TYPE_PRIORITY = {
3
15
  error: 0,
4
16
  pattern: 1,
@@ -8,6 +20,26 @@ const TYPE_PRIORITY = {
8
20
  const SESSION_DEFAULT_TTL_HOURS = 24;
9
21
  const RELEVANCE_BUMP = 0.05;
10
22
  const RELEVANCE_MAX = 1.0;
23
+ // v0.2.0 origin-aware ranking (K2-023, plan §B6.3 / D2-13).
24
+ // Applied as a multiplier on the base rank (FTS5 BM25 or -relevance_score).
25
+ // Reflectors lessons outrank pattern-miner lessons outrank agent-saved
26
+ // notes, all else equal. No embeddings, no RRF.
27
+ const ORIGIN_BOOST_REFLECTOR = 2;
28
+ const ORIGIN_BOOST_PATTERN = 1.5;
29
+ const ORIGIN_BOOST_AGENT = 1;
30
+ const RECENCY_DECAY_PER_DAY = 0.95; // newer = closer to 1 (less penalty)
31
+ function sqliteUtcToMs(createdAt) {
32
+ // SQLite `datetime('now')` returns 'YYYY-MM-DD HH:MM:SS' in UTC.
33
+ // JS Date can parse ISO 8601 with 'T' and 'Z'.
34
+ const iso = createdAt.includes("T")
35
+ ? createdAt
36
+ : `${createdAt.replace(" ", "T")}Z`;
37
+ const ms = Date.parse(iso);
38
+ return Number.isNaN(ms) ? Date.now() : ms;
39
+ }
40
+ // SQLite/better-sqlite3 surface both error code and message variants depending
41
+ // on the underlying driver (node:sqlite vs better-sqlite3). Match loosely.
42
+ const UNIQUE_VIOLATION_RE = /SQLITE_CONSTRAINT_UNIQUE|UNIQUE constraint failed/i;
11
43
  function sqliteUtcNowPlusHours(hours) {
12
44
  const d = new Date(Date.now() + hours * 3_600_000);
13
45
  const pad = (n) => String(n).padStart(2, "0");
@@ -28,6 +60,9 @@ function mapRow(row, score) {
28
60
  createdAt: row.created_at,
29
61
  updatedAt: row.updated_at,
30
62
  expiresAt: row.expires_at,
63
+ projectId: row.project_id ?? null,
64
+ fingerprint: row.fingerprint ?? null,
65
+ origin: row.origin ?? null,
31
66
  };
32
67
  if (score !== undefined) {
33
68
  if (!mem.metadata)
@@ -53,30 +88,81 @@ function isNotSearchable(mem) {
53
88
  return (mem.metadata?.not_searchable === true);
54
89
  }
55
90
  export class MemoryService {
56
- store;
57
- constructor(store) {
91
+ metrics;
92
+ constructor(store, metrics) {
58
93
  this.store = store;
94
+ this.metrics = metrics ?? null;
59
95
  }
96
+ // `store` is declared here (rather than as a constructor parameter property)
97
+ // so that Metrics can be added without changing the parameter order callers
98
+ // have been using since v0.1.0.
99
+ store;
60
100
  save(input) {
61
- const id = uuidv7();
62
101
  const scope = input.scope ?? "project";
63
102
  const relevanceScore = input.relevanceScore ?? 0.5;
64
103
  const metadata = input.metadata ? JSON.stringify(input.metadata) : null;
104
+ const origin = input.origin ?? "agent";
105
+ const projectId = input.projectId ?? null;
106
+ // Fingerprint is used for dedup (error memories via migration 003
107
+ // partial unique index) AND for pattern idempotency (K2-021 — pattern
108
+ // memories store an explicit fingerprint so PatternMiner's SELECT-before-
109
+ // INSERT idempotency check can find prior emissions). Callers may pass
110
+ // an explicit fingerprint for any type; we honor it verbatim. For
111
+ // type='error' only, we auto-compute from content when the caller left
112
+ // it absent.
113
+ let fp = null;
114
+ if (input.fingerprint) {
115
+ fp = input.fingerprint;
116
+ }
117
+ else if (input.type === "error") {
118
+ fp = computeFingerprint(input.content, projectId ?? undefined);
119
+ }
65
120
  let expiresAt = input.expiresAt ?? null;
66
121
  if (scope === "session" && !input.expiresAt) {
67
122
  expiresAt = sqliteUtcNowPlusHours(SESSION_DEFAULT_TTL_HOURS);
68
123
  }
69
- this.store
70
- .prepare(`INSERT INTO memories
71
- (id, type, content, scope, relevance_score, source_tool, source_session, metadata, expires_at)
72
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
73
- .run(id, input.type, input.content, scope, relevanceScore, input.sourceTool ?? null, input.sourceSession ?? null, metadata, expiresAt);
74
- return id;
124
+ const id = uuidv7();
125
+ try {
126
+ this.store
127
+ .prepare(`INSERT INTO memories
128
+ (id, type, content, scope, relevance_score, source_tool, source_session,
129
+ metadata, expires_at, project_id, fingerprint, origin)
130
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
131
+ .run(id, input.type, input.content, scope, relevanceScore, input.sourceTool ?? null, input.sourceSession ?? null, metadata, expiresAt, projectId, fp, origin);
132
+ return id;
133
+ }
134
+ catch (err) {
135
+ const msg = err?.message ?? "";
136
+ if (!UNIQUE_VIOLATION_RE.test(msg))
137
+ throw err;
138
+ // Dedup path enabled by migration 003 partial unique index
139
+ // `uq_memories_error_fp`. The index only fires for
140
+ // type='error' AND fingerprint NOT NULL AND origin='reflector', so
141
+ // an agent-saved identical error memory would NOT have collided.
142
+ if (fp === null || origin !== "reflector")
143
+ throw err;
144
+ const existing = this.store
145
+ .prepare(`SELECT id FROM memories
146
+ WHERE project_id IS ?
147
+ AND fingerprint = ?
148
+ AND type = 'error'
149
+ AND origin = 'reflector'
150
+ LIMIT 1`)
151
+ .get(projectId, fp);
152
+ this.metrics?.incr("duplicate_suppressions", 1);
153
+ if (existing)
154
+ return existing.id;
155
+ // Defensive: if the unique fired but the lookup returns nothing
156
+ // (concurrent delete race), fall through and rethrow rather than
157
+ // fabricate an id.
158
+ throw err;
159
+ }
75
160
  }
76
161
  getById(id) {
77
162
  const row = this.store
78
163
  .prepare(`SELECT id, type, content, scope, relevance_score, source_tool, source_session,
79
- metadata, created_at, updated_at, expires_at
164
+ metadata, created_at, updated_at, expires_at,
165
+ project_id, fingerprint, origin
80
166
  FROM memories WHERE id = ?`)
81
167
  .get(id);
82
168
  return row ? mapRow(row) : null;
@@ -121,14 +207,16 @@ export class MemoryService {
121
207
  }
122
208
  query(input) {
123
209
  const match = sanitizeMatch(input.text);
124
- if (!match)
125
- return [];
210
+ if (match.length === 0) {
211
+ return input.full === true ? [] : [];
212
+ }
126
213
  const scope = input.scope ?? "all";
127
214
  const limit = input.limit ?? 10;
128
215
  let sql = `
129
216
  SELECT m.id, m.type, m.content, m.scope, m.relevance_score,
130
217
  m.source_tool, m.source_session, m.metadata,
131
218
  m.created_at, m.updated_at, m.expires_at,
219
+ m.project_id, m.fingerprint, m.origin,
132
220
  bm25(memories_fts) AS score
133
221
  FROM memories_fts
134
222
  JOIN memories m ON m.rowid = memories_fts.rowid
@@ -146,14 +234,16 @@ export class MemoryService {
146
234
  sql += " ORDER BY bm25(memories_fts) LIMIT ?";
147
235
  params.push(limit);
148
236
  const rows = this.store.prepare(sql).all(...params);
149
- return rows
237
+ const memories = rows
150
238
  .map((r) => mapRow(r, r.score))
151
239
  .filter((m) => !isNotSearchable(m));
240
+ return input.full === true ? memories : memories.map(toSlim);
152
241
  }
153
242
  loadAll(scope) {
154
243
  let sql = `
155
244
  SELECT id, type, content, scope, relevance_score, source_tool, source_session,
156
- metadata, created_at, updated_at, expires_at
245
+ metadata, created_at, updated_at, expires_at,
246
+ project_id, fingerprint, origin
157
247
  FROM memories
158
248
  WHERE (expires_at IS NULL OR expires_at > datetime('now'))`;
159
249
  const params = [];
@@ -176,6 +266,7 @@ export class MemoryService {
176
266
  SELECT m.id, m.type, m.content, m.scope, m.relevance_score,
177
267
  m.source_tool, m.source_session, m.metadata,
178
268
  m.created_at, m.updated_at, m.expires_at,
269
+ m.project_id, m.fingerprint, m.origin,
179
270
  bm25(memories_fts) AS score
180
271
  FROM memories_fts
181
272
  JOIN memories m ON m.rowid = memories_fts.rowid
@@ -205,7 +296,10 @@ export class MemoryService {
205
296
  .map((r) => mapRow(r))
206
297
  .filter((m) => !isNotSearchable(m));
207
298
  }
208
- candidates.sort((a, b) => TYPE_PRIORITY[a.type] - TYPE_PRIORITY[b.type]);
299
+ // v0.2.0 (K2-023) origin-aware rank: BM25 × origin-boost × recency-decay.
300
+ // Tie-breakers preserve the v0.1.x spirit (errors/patterns before
301
+ // context; newer before older when nothing else decides).
302
+ candidates.sort((a, b) => rankCompare(a, b));
209
303
  const result = [];
210
304
  let used = 0;
211
305
  for (const mem of candidates) {
@@ -224,5 +318,78 @@ export class MemoryService {
224
318
  }
225
319
  return result;
226
320
  }
321
+ /**
322
+ * v0.2.0 (K2-026) — Feedback loop positive half (plan §B6.10 / D2-10).
323
+ *
324
+ * For each reflector-sourced error memory emitted during the given session
325
+ * whose fingerprint did NOT recur as a failing `tool_call` within the same
326
+ * project, bump `relevance_score` by `RELEVANCE_BUMP` (capped at
327
+ * `RELEVANCE_MAX`). Agent-saved memories are NEVER auto-boosted by this
328
+ * loop (anti-gaming guarantee, D2-06).
329
+ *
330
+ * Returns the number of memories that received a positive boost.
331
+ */
332
+ boostPositiveReflectors(sessionId) {
333
+ if (!sessionId)
334
+ return 0;
335
+ const lessons = this.store
336
+ .prepare(`SELECT id, fingerprint, project_id
337
+ FROM memories
338
+ WHERE origin = 'reflector'
339
+ AND type = 'error'
340
+ AND source_session = ?
341
+ AND fingerprint IS NOT NULL`)
342
+ .all(sessionId);
343
+ if (lessons.length === 0)
344
+ return 0;
345
+ const recurrenceCheck = this.store.prepare(`SELECT COUNT(*) AS c
346
+ FROM tool_calls
347
+ WHERE fingerprint = ?
348
+ AND success = 0
349
+ AND (project_id IS ? OR (project_id IS NULL AND ? IS NULL))`);
350
+ const bumpOne = this.store.prepare("UPDATE memories SET relevance_score = MIN(?, relevance_score + ?) WHERE id = ?");
351
+ let boosted = 0;
352
+ this.store.transaction(() => {
353
+ for (const l of lessons) {
354
+ const row = recurrenceCheck.get(l.fingerprint, l.project_id, l.project_id);
355
+ const c = row?.c ?? 0;
356
+ if (c === 0) {
357
+ bumpOne.run(RELEVANCE_MAX, RELEVANCE_BUMP, l.id);
358
+ boosted += 1;
359
+ }
360
+ }
361
+ });
362
+ return boosted;
363
+ }
364
+ }
365
+ function originBoost(mem) {
366
+ switch (mem.origin ?? "agent") {
367
+ case "reflector":
368
+ return ORIGIN_BOOST_REFLECTOR;
369
+ case "pattern":
370
+ return ORIGIN_BOOST_PATTERN;
371
+ default:
372
+ return ORIGIN_BOOST_AGENT;
373
+ }
374
+ }
375
+ function rankScore(mem) {
376
+ // FTS5 bm25 returns a negative score (more negative = better match).
377
+ // For non-FTS rows (loadAll path), fall back to -relevance_score so
378
+ // higher-relevance memories also come first under the same sign convention.
379
+ const rawScore = mem.metadata?.score;
380
+ const base = typeof rawScore === "number" ? rawScore : -mem.relevanceScore;
381
+ const ageDays = Math.max(0, (Date.now() - sqliteUtcToMs(mem.createdAt)) / 86_400_000);
382
+ const recencyDecay = RECENCY_DECAY_PER_DAY ** ageDays;
383
+ return base * originBoost(mem) * recencyDecay;
384
+ }
385
+ function rankCompare(a, b) {
386
+ const ra = rankScore(a);
387
+ const rb = rankScore(b);
388
+ if (ra !== rb)
389
+ return ra - rb; // ascending: most negative (best) first
390
+ if (TYPE_PRIORITY[a.type] !== TYPE_PRIORITY[b.type]) {
391
+ return TYPE_PRIORITY[a.type] - TYPE_PRIORITY[b.type];
392
+ }
393
+ return sqliteUtcToMs(b.createdAt) - sqliteUtcToMs(a.createdAt); // newer first
227
394
  }
228
395
  //# sourceMappingURL=MemoryService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryService.js","sourceRoot":"","sources":["../../plugin/MemoryService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MemoryService.js","sourceRoot":"","sources":["../../plugin/MemoryService.ts"],"names":[],"mappings":"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"}
@@ -4,10 +4,13 @@ export interface MigrateResult {
4
4
  to: string;
5
5
  applied: string[];
6
6
  }
7
+ export type PostApplyHook = (store: Store) => void;
7
8
  export declare class Migrate {
8
9
  private store;
9
10
  private migrationsDir;
10
- constructor(store: Store, migrationsDir: string);
11
+ private readonly postApplyHooks;
12
+ constructor(store: Store, migrationsDir: string, postApplyHooks?: Record<string, PostApplyHook>);
13
+ registerPostApply(version: string, hook: PostApplyHook): void;
11
14
  run(): Promise<MigrateResult>;
12
15
  private listPending;
13
16
  }
@@ -1,11 +1,35 @@
1
1
  import { readFileSync, readdirSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ // Built-in post-apply hooks, keyed by migration version. Each hook runs inside
4
+ // the same transaction as the migration's DDL, so a hook failure rolls back the
5
+ // whole migration. Hooks are only invoked when their version is being applied
6
+ // (i.e., not already present in schema_version).
7
+ const DEFAULT_POST_APPLY_HOOKS = {
8
+ // v0.2.0 Signal Quality: defensive backfill of memories.origin for legacy
9
+ // rows. The column is NOT NULL DEFAULT 'agent', so SQLite already populates
10
+ // pre-existing rows with 'agent' on ALTER TABLE. This hook is a belt-and-
11
+ // braces UPDATE that coerces any NULL/empty stragglers (which would only
12
+ // exist if a partial DB skipped the DEFAULT) back to 'agent'.
13
+ "003": (store) => {
14
+ store
15
+ .prepare("UPDATE memories SET origin = 'agent' WHERE origin IS NULL OR origin = ''")
16
+ .run();
17
+ },
18
+ };
3
19
  export class Migrate {
4
20
  store;
5
21
  migrationsDir;
6
- constructor(store, migrationsDir) {
22
+ postApplyHooks;
23
+ constructor(store, migrationsDir, postApplyHooks) {
7
24
  this.store = store;
8
25
  this.migrationsDir = migrationsDir;
26
+ this.postApplyHooks = new Map(Object.entries({
27
+ ...DEFAULT_POST_APPLY_HOOKS,
28
+ ...(postApplyHooks ?? {}),
29
+ }));
30
+ }
31
+ registerPostApply(version, hook) {
32
+ this.postApplyHooks.set(version, hook);
9
33
  }
10
34
  async run() {
11
35
  this.store.exec(`CREATE TABLE IF NOT EXISTS schema_version (
@@ -25,6 +49,9 @@ export class Migrate {
25
49
  const sql = readFileSync(join(this.migrationsDir, migration.file), "utf8");
26
50
  this.store.transaction(() => {
27
51
  this.store.exec(sql);
52
+ const hook = this.postApplyHooks.get(migration.version);
53
+ if (hook)
54
+ hook(this.store);
28
55
  insertVersion.run(migration.version);
29
56
  });
30
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Migrate.js","sourceRoot":"","sources":["../../plugin/Migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AASjC,MAAM,OAAO,OAAO;IAEV;IACA;IAFT,YACS,KAAY,EACZ,aAAqB;QADrB,UAAK,GAAL,KAAK,CAAO;QACZ,kBAAa,GAAb,aAAa,CAAQ;IAC3B,CAAC;IAEJ,KAAK,CAAC,GAAG;QACR,IAAI,CAAC,KAAK,CAAC,IAAI,CACd;;;UAGO,CACP,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK;aAC3B,OAAO,CACP,kEAAkE,CAClE;aACA,GAAG,EAAqC,CAAC;QAE3C,MAAM,IAAI,GAAG,UAAU,EAAE,OAAO,IAAI,KAAK,CAAC;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAEvC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACxC,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CACvC,2DAA2D,CAC3D,CAAC;QAEF,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;YACjC,MAAM,GAAG,GAAG,YAAY,CACvB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,IAAI,CAAC,EACxC,MAAM,CACN,CAAC;YACF,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;gBAC3B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrB,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;QACJ,CAAC;QAED,OAAO;YACN,IAAI;YACJ,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO;YACvC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;SACtC,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,OAAe;QAClC,IAAI,KAAK,GAAa,EAAE,CAAC;QACzB,IAAI,CAAC;YACJ,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3E,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,EAAE,CAAC;QACX,CAAC;QACD,KAAK,CAAC,IAAI,EAAE,CAAC;QACb,OAAO,KAAK;aACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACrC,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACnD,CAAC,CAAC;aACD,MAAM,CACN,CAAC,CAAC,EAA0C,EAAE,CAC7C,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,GAAG,OAAO,CAClC,CAAC;IACJ,CAAC;CACD"}
1
+ {"version":3,"file":"Migrate.js","sourceRoot":"","sources":["../../plugin/Migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import type { MemoryService } from "./MemoryService.js";
2
+ import type { Store } from "./Store.js";
3
+ import type { Metrics } from "./metrics.js";
4
+ /**
5
+ * v0.2.0 PatternMiner (K2-021, plan §B6.10 / D2-08).
6
+ *
7
+ * Opt-in deterministic pattern miner. Reads recent `tool_calls` for a given
8
+ * project, groups consecutive ordered 2-grams of `(tool_name)` and 3-grams
9
+ * where the *middle* tool was a failure, and when a group reaches the
10
+ * threshold (default `N ≥ 5` distinct sessions), emits a single
11
+ * `type='pattern'`, `origin='pattern'` memory describing the pattern.
12
+ *
13
+ * Default OFF — must be enabled by setting `kevin_settings.patternminer_enabled`
14
+ * to `'1'`. Idempotent via SELECT-before-INSERT keyed on
15
+ * `(project_id, fingerprint, type='pattern', origin='pattern')`. Migration 003's
16
+ * partial UNIQUE index only covers `type='error' AND origin='reflector'`, so
17
+ * pattern memories cannot rely on a database uniqueness constraint — the
18
+ * SELECT check inside `mine()` is the single idempotency mechanism.
19
+ *
20
+ * NO LLM hop (D2-08). The emitted suggestion is a deterministic template built
21
+ * from the captured tool names.
22
+ */
23
+ export interface PatternMinerOptions {
24
+ /** Minimum distinct sessions a pattern must appear in before emission.
25
+ * Default 5 (D2-08). */
26
+ threshold?: number;
27
+ }
28
+ export declare class PatternMiner {
29
+ private readonly store;
30
+ private readonly memoryService;
31
+ private readonly metrics;
32
+ private readonly threshold;
33
+ constructor(store: Store, memoryService: MemoryService, metrics?: Metrics | null, options?: PatternMinerOptions);
34
+ /**
35
+ * Mine patterns observed in `tool_calls` for the given project. Returns the
36
+ * number of NEW `pattern` memories emitted this cycle.
37
+ *
38
+ * When the opt-in flag `kevin_settings.patternminer_enabled` is not set to
39
+ * `'1'` (default), this is a no-op and returns 0.
40
+ *
41
+ * When `projectId` is null/undefined, mines tool_calls whose `project_id`
42
+ * IS NULL (legacy / opt-out flow). When `projectId` is a string, mines
43
+ * tool_calls scoped to that project only.
44
+ */
45
+ mine(projectId?: string | null): number;
46
+ private isEnabled;
47
+ private fetchToolCalls;
48
+ private collectCandidates;
49
+ }
@@ -0,0 +1,133 @@
1
+ import { fingerprint as computeFingerprint } from "./fingerprint.js";
2
+ const DEFAULT_THRESHOLD = 5;
3
+ const SETTING_KEY = "patternminer_enabled";
4
+ export class PatternMiner {
5
+ store;
6
+ memoryService;
7
+ metrics;
8
+ threshold;
9
+ constructor(store, memoryService, metrics, options) {
10
+ this.store = store;
11
+ this.memoryService = memoryService;
12
+ this.metrics = metrics ?? null;
13
+ this.threshold = options?.threshold ?? DEFAULT_THRESHOLD;
14
+ }
15
+ /**
16
+ * Mine patterns observed in `tool_calls` for the given project. Returns the
17
+ * number of NEW `pattern` memories emitted this cycle.
18
+ *
19
+ * When the opt-in flag `kevin_settings.patternminer_enabled` is not set to
20
+ * `'1'` (default), this is a no-op and returns 0.
21
+ *
22
+ * When `projectId` is null/undefined, mines tool_calls whose `project_id`
23
+ * IS NULL (legacy / opt-out flow). When `projectId` is a string, mines
24
+ * tool_calls scoped to that project only.
25
+ */
26
+ mine(projectId) {
27
+ if (!this.isEnabled())
28
+ return 0;
29
+ const rows = this.fetchToolCalls(projectId ?? null);
30
+ if (rows.length === 0)
31
+ return 0;
32
+ const candidates = this.collectCandidates(rows);
33
+ if (candidates.length === 0)
34
+ return 0;
35
+ let emitted = 0;
36
+ for (const c of candidates) {
37
+ if (c.sessions.size < this.threshold)
38
+ continue;
39
+ const fp = computeFingerprint(c.content, projectId ?? undefined);
40
+ // Idempotency: migration 003's partial unique only covers
41
+ // (type='error', origin='reflector'). For pattern memories we
42
+ // SELECT to detect a prior emission with the same
43
+ // (project_id, fingerprint, type='pattern', origin='pattern').
44
+ const existing = this.store
45
+ .prepare(`SELECT id FROM memories
46
+ WHERE type = 'pattern' AND origin = 'pattern'
47
+ AND fingerprint = ?
48
+ AND (project_id IS ? OR (project_id IS NULL AND ? IS NULL))
49
+ LIMIT 1`)
50
+ .get(fp, projectId ?? null, projectId ?? null);
51
+ if (existing)
52
+ continue;
53
+ this.memoryService.save({
54
+ type: "pattern",
55
+ origin: "pattern",
56
+ fingerprint: fp,
57
+ content: c.content,
58
+ scope: "project",
59
+ projectId: projectId ?? undefined,
60
+ relevanceScore: 0.5,
61
+ sourceTool: "PatternMiner",
62
+ });
63
+ this.metrics?.incr("patterns_mined", 1);
64
+ emitted += 1;
65
+ }
66
+ return emitted;
67
+ }
68
+ isEnabled() {
69
+ const row = this.store
70
+ .prepare("SELECT value FROM kevin_settings WHERE key = ?")
71
+ .get(SETTING_KEY);
72
+ return row?.value === "1";
73
+ }
74
+ fetchToolCalls(projectId) {
75
+ const nullPid = projectId === null || projectId === undefined;
76
+ const sql = nullPid
77
+ ? `SELECT id, session_id, ts, tool, success FROM tool_calls
78
+ WHERE project_id IS NULL
79
+ ORDER BY session_id ASC, ts ASC`
80
+ : `SELECT id, session_id, ts, tool, success FROM tool_calls
81
+ WHERE project_id = ?
82
+ ORDER BY session_id ASC, ts ASC`;
83
+ const stmt = this.store.prepare(sql);
84
+ const rows = (nullPid ? stmt.all() : stmt.all(projectId));
85
+ return rows;
86
+ }
87
+ collectCandidates(rows) {
88
+ // Group rows by session_id preserving arrival order. The SQL already
89
+ // orders by (session_id ASC, ts ASC), so a sequential scan yields each
90
+ // session's tool_calls in execution order.
91
+ const bySession = new Map();
92
+ for (const r of rows) {
93
+ let list = bySession.get(r.session_id);
94
+ if (!list) {
95
+ list = [];
96
+ bySession.set(r.session_id, list);
97
+ }
98
+ list.push(r);
99
+ }
100
+ // 2-grams: ordered pair (a, b) of consecutive tool names per session.
101
+ // 3-grams: ordered triple (a, b, c) where the middle tool b failed
102
+ // (success = 0). These capture the "X→Y fails then Z" lifecycle that
103
+ // the plan §B6.10 calls out.
104
+ const map = new Map();
105
+ const record = (key, content, sessionId) => {
106
+ let cand = map.get(key);
107
+ if (!cand) {
108
+ cand = { key, content, sessions: new Set() };
109
+ map.set(key, cand);
110
+ }
111
+ cand.sessions.add(sessionId);
112
+ };
113
+ for (const [sessionId, list] of bySession) {
114
+ for (let i = 0; i < list.length - 1; i++) {
115
+ const a = list[i];
116
+ const b = list[i + 1];
117
+ const key2 = `2g::${a.tool}::${b.tool}`;
118
+ const content2 = `Pattern: tool "${a.tool}" followed by tool "${b.tool}". Review the ${a.tool}→${b.tool} contract before retrying.`;
119
+ record(key2, content2, sessionId);
120
+ if (i + 2 < list.length) {
121
+ const c = list[i + 2];
122
+ if (b.success === 0) {
123
+ const key3 = `3g::${a.tool}::${b.tool}::${c.tool}`;
124
+ const content3 = `Pattern: tool "${a.tool}" followed by failing tool "${b.tool}" then tool "${c.tool}". Review the ${a.tool}→${b.tool}(failed)→${c.tool} contract before retrying.`;
125
+ record(key3, content3, sessionId);
126
+ }
127
+ }
128
+ }
129
+ }
130
+ return Array.from(map.values());
131
+ }
132
+ }
133
+ //# sourceMappingURL=PatternMiner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PatternMiner.js","sourceRoot":"","sources":["../../plugin/PatternMiner.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { MemoryService } from "./MemoryService.js";
2
+ import type { Metrics } from "./metrics.js";
2
3
  export interface ReflectionInput {
3
4
  toolName: string;
4
5
  argsSummary: string;
@@ -7,6 +8,8 @@ export interface ReflectionInput {
7
8
  exitCode?: number;
8
9
  errorType: string;
9
10
  sessionId: string;
11
+ /** Optional project scope for v0.2.0 dedup + per-fingerprint throttle. */
12
+ projectId?: string | null;
10
13
  }
11
14
  export interface ReflectorOptions {
12
15
  throttleMs?: number;
@@ -15,16 +18,40 @@ export interface HeuristicLessonInput {
15
18
  toolName: string;
16
19
  errorType: string;
17
20
  firstErrorLine: string;
21
+ /** v0.2.0 (K2-018) — optional pre-computed dispatch result. When absent,
22
+ * dispatch is performed on `firstErrorLine` alone. */
23
+ dispatched?: DispatchedLesson | null;
24
+ }
25
+ /** Result of the per-error-code deterministic rule dispatch (K2-018 / D2-09). */
26
+ export interface DispatchedLesson {
27
+ /** Stable short code captured from the source output (e.g. `TS2304`,
28
+ * `EADDRINUSE`, `F401`, the captured `Error: <Name>` class, the failing
29
+ * command string). `null` when no rule matches (fallback path). */
30
+ code: string | null;
31
+ /** Short deterministic hint, e.g. `import or typo`, `review syscall:
32
+ * EADDRINUSE`. `null` when `code` is null (the v0.1.x fallback path). */
33
+ hint: string | null;
18
34
  }
19
35
  export declare const ERROR_LINE_RE: RegExp;
20
36
  export declare const STRONG_ERROR_RE: RegExp;
21
37
  export declare class Reflector {
22
38
  private memoryService;
23
- private lastReflectionTs;
39
+ private lastReflectionByFp;
24
40
  private throttleMs;
25
- constructor(memoryService: MemoryService, options?: ReflectorOptions);
41
+ private metrics;
42
+ constructor(memoryService: MemoryService, options?: ReflectorOptions, metrics?: Metrics | null);
26
43
  invoke(input: ReflectionInput): Promise<string | null>;
27
44
  generateHeuristicLesson(input: HeuristicLessonInput): string;
45
+ /**
46
+ * v0.2.0 (K2-018 / D2-09) — deterministic per-error-code rule dispatch.
47
+ * Pure regex sweep over `stderr + '\n' + stdout` with NO LLM hop. Returns
48
+ * a short stable `code` + `hint` pair when a known rule matches, or
49
+ * `{ code: null, hint: null }` for the v0.1.x fallback path (which keeps
50
+ * the v0.1.x `SUGGESTIONS[errorType]` suggestion verbatim).
51
+ *
52
+ * Exported for unit testing (K2-019).
53
+ */
54
+ dispatchLesson(stderr: string, stdout: string, errorType: string): DispatchedLesson;
28
55
  redactPaths(text: string): string;
29
56
  redactSecrets(text: string): string;
30
57
  private extractFirstErrorLine;