@getplumb/core 0.1.6 → 0.4.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 (84) hide show
  1. package/README.md +2 -2
  2. package/dist/context-builder.d.ts +1 -7
  3. package/dist/context-builder.d.ts.map +1 -1
  4. package/dist/context-builder.js +7 -44
  5. package/dist/context-builder.js.map +1 -1
  6. package/dist/embedder.d.ts +16 -2
  7. package/dist/embedder.d.ts.map +1 -1
  8. package/dist/embedder.js +23 -4
  9. package/dist/embedder.js.map +1 -1
  10. package/dist/extraction-queue.d.ts +13 -3
  11. package/dist/extraction-queue.d.ts.map +1 -1
  12. package/dist/extraction-queue.js +21 -4
  13. package/dist/extraction-queue.js.map +1 -1
  14. package/dist/extractor.d.ts +2 -1
  15. package/dist/extractor.d.ts.map +1 -1
  16. package/dist/extractor.js +106 -7
  17. package/dist/extractor.js.map +1 -1
  18. package/dist/extractor.test.d.ts +2 -0
  19. package/dist/extractor.test.d.ts.map +1 -0
  20. package/dist/extractor.test.js +158 -0
  21. package/dist/extractor.test.js.map +1 -0
  22. package/dist/fact-search.d.ts +9 -5
  23. package/dist/fact-search.d.ts.map +1 -1
  24. package/dist/fact-search.js +25 -16
  25. package/dist/fact-search.js.map +1 -1
  26. package/dist/fact-search.test.d.ts +12 -0
  27. package/dist/fact-search.test.d.ts.map +1 -0
  28. package/dist/fact-search.test.js +117 -0
  29. package/dist/fact-search.test.js.map +1 -0
  30. package/dist/index.d.ts +6 -10
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2 -5
  33. package/dist/index.js.map +1 -1
  34. package/dist/llm-client.d.ts +11 -2
  35. package/dist/llm-client.d.ts.map +1 -1
  36. package/dist/llm-client.js +47 -3
  37. package/dist/llm-client.js.map +1 -1
  38. package/dist/local-store.d.ts +19 -63
  39. package/dist/local-store.d.ts.map +1 -1
  40. package/dist/local-store.js +353 -262
  41. package/dist/local-store.js.map +1 -1
  42. package/dist/local-store.test.d.ts +2 -0
  43. package/dist/local-store.test.d.ts.map +1 -0
  44. package/dist/local-store.test.js +146 -0
  45. package/dist/local-store.test.js.map +1 -0
  46. package/dist/raw-log-search.d.ts +9 -5
  47. package/dist/raw-log-search.d.ts.map +1 -1
  48. package/dist/raw-log-search.js +107 -29
  49. package/dist/raw-log-search.js.map +1 -1
  50. package/dist/raw-log-search.test.d.ts +12 -0
  51. package/dist/raw-log-search.test.d.ts.map +1 -0
  52. package/dist/raw-log-search.test.js +124 -0
  53. package/dist/raw-log-search.test.js.map +1 -0
  54. package/dist/read-path.d.ts +6 -23
  55. package/dist/read-path.d.ts.map +1 -1
  56. package/dist/read-path.js +9 -48
  57. package/dist/read-path.js.map +1 -1
  58. package/dist/read-path.test.d.ts +15 -0
  59. package/dist/read-path.test.d.ts.map +1 -0
  60. package/dist/read-path.test.js +393 -0
  61. package/dist/read-path.test.js.map +1 -0
  62. package/dist/schema.d.ts +4 -13
  63. package/dist/schema.d.ts.map +1 -1
  64. package/dist/schema.js +42 -52
  65. package/dist/schema.js.map +1 -1
  66. package/dist/scorer.d.ts +0 -9
  67. package/dist/scorer.d.ts.map +1 -1
  68. package/dist/scorer.js +1 -31
  69. package/dist/scorer.js.map +1 -1
  70. package/dist/scorer.test.d.ts +10 -0
  71. package/dist/scorer.test.d.ts.map +1 -0
  72. package/dist/scorer.test.js +169 -0
  73. package/dist/scorer.test.js.map +1 -0
  74. package/dist/store.d.ts +2 -14
  75. package/dist/store.d.ts.map +1 -1
  76. package/dist/types.d.ts +0 -25
  77. package/dist/types.d.ts.map +1 -1
  78. package/dist/types.js +1 -6
  79. package/dist/types.js.map +1 -1
  80. package/dist/wasm-db.d.ts +63 -8
  81. package/dist/wasm-db.d.ts.map +1 -1
  82. package/dist/wasm-db.js +124 -31
  83. package/dist/wasm-db.js.map +1 -1
  84. package/package.json +14 -2
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Cross-session AI memory — storage abstraction, types, and local SQLite driver
4
4
 
5
- The core library for [Plumb](https://getplumb.dev) — a local-first, MCP-native memory layer for AI agents.
5
+ The core library for [Plumb](https://plumb.run) — a local-first, MCP-native memory layer for AI agents.
6
6
 
7
7
  ## What it does
8
8
 
@@ -42,7 +42,7 @@ const results = await store.searchRawLog('TypeScript preferences', 5);
42
42
 
43
43
  - [Docs](https://docs.getplumb.dev)
44
44
  - [GitHub](https://github.com/getplumb/plumb)
45
- - [getplumb.dev](https://getplumb.dev)
45
+ - [plumb.run](https://plumb.run)
46
46
 
47
47
  ## License
48
48
 
@@ -6,12 +6,6 @@
6
6
  *
7
7
  * [MEMORY CONTEXT]
8
8
  *
9
- * ## High confidence facts
10
- * - user is building a product called Plumb (0.98, session: tech-planning, today)
11
- *
12
- * ## Medium confidence facts
13
- * - user uses TypeScript (0.65, session: dev-chat, 2 days ago)
14
- *
15
9
  * ## Related conversations
16
10
  * - [tech-planning] today: "Let me help you design the memory system..."
17
11
  *
@@ -26,7 +20,7 @@ export declare function formatAge(ageInDays: number): string;
26
20
  /**
27
21
  * Formats a MemoryContext into a [MEMORY CONTEXT] prompt block.
28
22
  *
29
- * Returns an empty string if the context has no facts and no raw chunks,
23
+ * Returns an empty string if the context has no raw chunks,
30
24
  * so callers can skip injection without additional checks.
31
25
  */
32
26
  export declare function formatContextBlock(context: MemoryContext): string;
@@ -1 +1 @@
1
- {"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../src/context-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAwB,MAAM,gBAAgB,CAAC;AAI1E;;;GAGG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAUnD;AAsBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAsCjE"}
1
+ {"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../src/context-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAY,MAAM,gBAAgB,CAAC;AAI9D;;;GAGG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAUnD;AAcD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAYjE"}
@@ -6,12 +6,6 @@
6
6
  *
7
7
  * [MEMORY CONTEXT]
8
8
  *
9
- * ## High confidence facts
10
- * - user is building a product called Plumb (0.98, session: tech-planning, today)
11
- *
12
- * ## Medium confidence facts
13
- * - user uses TypeScript (0.65, session: dev-chat, 2 days ago)
14
- *
15
9
  * ## Related conversations
16
10
  * - [tech-planning] today: "Let me help you design the memory system..."
17
11
  *
@@ -42,13 +36,6 @@ export function formatAge(ageInDays) {
42
36
  return `${Math.floor(ageInDays / 365)} years ago`;
43
37
  }
44
38
  // ─── Line formatters ──────────────────────────────────────────────────────────
45
- function formatFactLine(sf) {
46
- const { fact, score, ageInDays } = sf;
47
- const description = `${fact.subject} ${fact.predicate} ${fact.object}`;
48
- const sessionLabel = fact.sourceSessionLabel ?? fact.sourceSessionId;
49
- const age = formatAge(ageInDays);
50
- return `- ${description} (${score.toFixed(2)}, session: ${sessionLabel}, ${age})`;
51
- }
52
39
  function formatChunkLine(chunk) {
53
40
  const excerpt = chunk.chunkText.slice(0, 200);
54
41
  const sessionLabel = chunk.sessionLabel ?? chunk.sessionId;
@@ -60,42 +47,18 @@ function formatChunkLine(chunk) {
60
47
  /**
61
48
  * Formats a MemoryContext into a [MEMORY CONTEXT] prompt block.
62
49
  *
63
- * Returns an empty string if the context has no facts and no raw chunks,
50
+ * Returns an empty string if the context has no raw chunks,
64
51
  * so callers can skip injection without additional checks.
65
52
  */
66
53
  export function formatContextBlock(context) {
67
- const { highConfidence, mediumConfidence, lowConfidence, relatedConversations } = context;
68
- const isEmpty = highConfidence.length === 0 &&
69
- mediumConfidence.length === 0 &&
70
- lowConfidence.length === 0 &&
71
- relatedConversations.length === 0;
72
- if (isEmpty)
54
+ const { relatedConversations } = context;
55
+ if (relatedConversations.length === 0)
73
56
  return '';
74
57
  const lines = ['[MEMORY CONTEXT]'];
75
- if (highConfidence.length > 0) {
76
- lines.push('');
77
- lines.push('## High confidence facts');
78
- for (const sf of highConfidence)
79
- lines.push(formatFactLine(sf));
80
- }
81
- if (mediumConfidence.length > 0) {
82
- lines.push('');
83
- lines.push('## Medium confidence facts');
84
- for (const sf of mediumConfidence)
85
- lines.push(formatFactLine(sf));
86
- }
87
- if (lowConfidence.length > 0) {
88
- lines.push('');
89
- lines.push('## Low confidence facts');
90
- for (const sf of lowConfidence)
91
- lines.push(formatFactLine(sf));
92
- }
93
- if (relatedConversations.length > 0) {
94
- lines.push('');
95
- lines.push('## Related conversations');
96
- for (const chunk of relatedConversations)
97
- lines.push(formatChunkLine(chunk));
98
- }
58
+ lines.push('');
59
+ lines.push('## Related conversations');
60
+ for (const chunk of relatedConversations)
61
+ lines.push(formatChunkLine(chunk));
99
62
  return lines.join('\n');
100
63
  }
101
64
  //# sourceMappingURL=context-builder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-builder.js","sourceRoot":"","sources":["../src/context-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context-builder.js","sourceRoot":"","sources":["../src/context-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,iFAAiF;AAEjF;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,SAAiB;IACzC,IAAI,SAAS,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IAClC,IAAI,SAAS,GAAG,CAAC;QAAE,OAAO,WAAW,CAAC;IACtC,IAAI,SAAS,GAAG,CAAC;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC;IAC9D,IAAI,SAAS,GAAG,EAAE;QAAE,OAAO,YAAY,CAAC;IACxC,IAAI,SAAS,GAAG,EAAE;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,YAAY,CAAC;IACpE,IAAI,SAAS,GAAG,EAAE;QAAE,OAAO,aAAa,CAAC;IACzC,IAAI,SAAS,GAAG,GAAG;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC,aAAa,CAAC;IACvE,IAAI,SAAS,GAAG,GAAG;QAAE,OAAO,YAAY,CAAC;IACzC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC;AACpD,CAAC;AAED,iFAAiF;AAEjF,SAAS,eAAe,CAAC,KAAe;IACtC,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9C,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,SAAS,CAAC;IAC3D,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IACpF,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,OAAO,MAAM,YAAY,KAAK,GAAG,MAAM,OAAO,GAAG,CAAC;AACpD,CAAC;AAED,iFAAiF;AAEjF;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAsB;IACvD,MAAM,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC;IAEzC,IAAI,oBAAoB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjD,MAAM,KAAK,GAAa,CAAC,kBAAkB,CAAC,CAAC;IAE7C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACvC,KAAK,MAAM,KAAK,IAAI,oBAAoB;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IAE7E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -16,8 +16,8 @@
16
16
  export declare const EMBED_DIM = 384;
17
17
  /**
18
18
  * Embed a passage for indexing (no query prefix).
19
- * Returns a normalized Float32Array of length EMBED_DIM, or a zero vector
20
- * if @xenova/transformers is not available (graceful degradation).
19
+ * Returns a normalized Float32Array of length EMBED_DIM.
20
+ * Throws if @xenova/transformers is not available or embedding fails.
21
21
  */
22
22
  export declare function embed(text: string): Promise<Float32Array>;
23
23
  /**
@@ -33,4 +33,18 @@ export declare function embedQuery(query: string): Promise<Float32Array>;
33
33
  * should detect all-zero arrays and fall back to RRF order.
34
34
  */
35
35
  export declare function rerankScores(query: string, passages: string[]): Promise<number[]>;
36
+ /**
37
+ * Warm the embedder pipeline at initialization time.
38
+ * Loads and JIT-compiles the Xenova model to eliminate first-query cold-start latency.
39
+ * No-op if @xenova/transformers is unavailable.
40
+ */
41
+ export declare function warmEmbedder(): Promise<void>;
42
+ /**
43
+ * Warm the reranker pipeline at initialization time.
44
+ * Loads and JIT-compiles the cross-encoder model (~80MB) to eliminate first-query cold-start latency.
45
+ * Adds ~200ms to startup and increases memory footprint, but ensures consistent <250ms query performance
46
+ * from the first query onward (without warming, first query sees ~360ms, subsequent queries ~210ms).
47
+ * No-op if @xenova/transformers is unavailable.
48
+ */
49
+ export declare function warmReranker(): Promise<void>;
36
50
  //# sourceMappingURL=embedder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"embedder.d.ts","sourceRoot":"","sources":["../src/embedder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,sDAAsD;AACtD,eAAO,MAAM,SAAS,MAAM,CAAC;AA2B7B;;;;GAIG;AACH,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAK/D;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAKrE;AA+BD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBvF"}
1
+ {"version":3,"file":"embedder.d.ts","sourceRoot":"","sources":["../src/embedder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,sDAAsD;AACtD,eAAO,MAAM,SAAS,MAAM,CAAC;AA2B7B;;;;GAIG;AACH,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAO/D;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAKrE;AA+BD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBvF;AAED;;;;GAIG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAElD;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAElD"}
package/dist/embedder.js CHANGED
@@ -39,13 +39,14 @@ async function getEmbedPipeline() {
39
39
  }
40
40
  /**
41
41
  * Embed a passage for indexing (no query prefix).
42
- * Returns a normalized Float32Array of length EMBED_DIM, or a zero vector
43
- * if @xenova/transformers is not available (graceful degradation).
42
+ * Returns a normalized Float32Array of length EMBED_DIM.
43
+ * Throws if @xenova/transformers is not available or embedding fails.
44
44
  */
45
45
  export async function embed(text) {
46
46
  const pipe = await getEmbedPipeline();
47
- if (pipe === null)
48
- return new Float32Array(EMBED_DIM);
47
+ if (pipe === null) {
48
+ throw new Error('Embedder not available: @xenova/transformers failed to load');
49
+ }
49
50
  const output = await pipe(text, { pooling: 'mean', normalize: true });
50
51
  return new Float32Array(output.data);
51
52
  }
@@ -104,4 +105,22 @@ export async function rerankScores(query, passages) {
104
105
  }
105
106
  return scores;
106
107
  }
108
+ /**
109
+ * Warm the embedder pipeline at initialization time.
110
+ * Loads and JIT-compiles the Xenova model to eliminate first-query cold-start latency.
111
+ * No-op if @xenova/transformers is unavailable.
112
+ */
113
+ export async function warmEmbedder() {
114
+ await getEmbedPipeline();
115
+ }
116
+ /**
117
+ * Warm the reranker pipeline at initialization time.
118
+ * Loads and JIT-compiles the cross-encoder model (~80MB) to eliminate first-query cold-start latency.
119
+ * Adds ~200ms to startup and increases memory footprint, but ensures consistent <250ms query performance
120
+ * from the first query onward (without warming, first query sees ~360ms, subsequent queries ~210ms).
121
+ * No-op if @xenova/transformers is unavailable.
122
+ */
123
+ export async function warmReranker() {
124
+ await getRerankPipeline();
125
+ }
107
126
  //# sourceMappingURL=embedder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"embedder.js","sourceRoot":"","sources":["../src/embedder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"embedder.js","sourceRoot":"","sources":["../src/embedder.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,22 @@
1
1
  import type { MessageExchange, Fact } from './types.js';
2
2
  /**
3
3
  * Extraction function signature expected by ExtractionQueue.
4
- * Takes an exchange and userId, returns extracted facts.
4
+ * Takes an exchange, userId, and sourceChunkId, returns extracted facts.
5
5
  * LocalStore binds extractFacts with its own store + llmConfig.
6
+ * T-079: Added sourceChunkId to link extracted facts back to raw_log chunk.
6
7
  */
7
- export type ExtractFn = (exchange: MessageExchange, userId: string) => Promise<Fact[]>;
8
+ export type ExtractFn = (exchange: MessageExchange, userId: string, sourceChunkId: string) => Promise<Fact[]>;
8
9
  export interface ExtractionQueueOptions {
9
10
  /** Drain interval in milliseconds. Defaults to PLUMB_EXTRACT_INTERVAL_MS env var or 300000 (5 min). */
10
11
  intervalMs?: number;
11
12
  /** Max queue size before early flush. Defaults to PLUMB_EXTRACT_BATCH_SIZE env var or 10. */
12
13
  batchSize?: number;
14
+ /**
15
+ * Delay between individual extraction calls within a flush batch (ms).
16
+ * Defaults to PLUMB_EXTRACT_ITEM_DELAY_MS env var or 6500ms.
17
+ * Set to pace requests within LLM provider rate limits (e.g. Gemini free tier: 10 RPM = 1 req/6s).
18
+ */
19
+ itemDelayMs?: number;
13
20
  }
14
21
  /**
15
22
  * ExtractionQueue — batched fact extraction queue.
@@ -35,13 +42,15 @@ export declare class ExtractionQueue {
35
42
  private timer;
36
43
  private readonly intervalMs;
37
44
  private readonly batchSize;
45
+ private readonly itemDelayMs;
38
46
  private flushing;
39
47
  constructor(extractFn: ExtractFn, opts?: ExtractionQueueOptions);
40
48
  /**
41
49
  * Enqueue an exchange for fact extraction.
42
50
  * Triggers early flush if batch size threshold is reached.
51
+ * T-079: Added sourceChunkId parameter to link extracted facts back to raw_log chunk.
43
52
  */
44
- enqueue(exchange: MessageExchange, userId: string): void;
53
+ enqueue(exchange: MessageExchange, userId: string, sourceChunkId: string): void;
45
54
  /**
46
55
  * Start the background drain loop.
47
56
  * Call this once after construction (e.g., in plugin activate()).
@@ -56,6 +65,7 @@ export declare class ExtractionQueue {
56
65
  * Flush the queue immediately: drain all pending items and call extractFn for each.
57
66
  * Uses Promise.allSettled() so one failed extraction doesn't drop others.
58
67
  * Safe to call concurrently — only one flush runs at a time.
68
+ * T-079: Pass sourceChunkId to extractFn for processing state machine.
59
69
  */
60
70
  flush(): Promise<void>;
61
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"extraction-queue.d.ts","sourceRoot":"","sources":["../src/extraction-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAExD;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAIvF,MAAM,WAAW,sBAAsB;IACrC,uGAAuG;IACvG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6FAA6F;IAC7F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,eAAe;IAQxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAP5B,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAS;gBAGN,SAAS,EAAE,SAAS,EACrC,IAAI,CAAC,EAAE,sBAAsB;IAM/B;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAOxD;;;OAGG;IACH,KAAK,IAAI,IAAI;IAKb;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAkB7B"}
1
+ {"version":3,"file":"extraction-queue.d.ts","sourceRoot":"","sources":["../src/extraction-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,KAClB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAQrB,MAAM,WAAW,sBAAsB;IACrC,uGAAuG;IACvG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6FAA6F;IAC7F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,eAAe;IASxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAR5B,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAS;gBAGN,SAAS,EAAE,SAAS,EACrC,IAAI,CAAC,EAAE,sBAAsB;IAO/B;;;;OAIG;IACH,OAAO,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI;IAO/E;;;OAGG;IACH,KAAK,IAAI,IAAI;IAKb;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B;;;;;OAKG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CA4B7B"}
@@ -22,18 +22,21 @@ export class ExtractionQueue {
22
22
  timer = null;
23
23
  intervalMs;
24
24
  batchSize;
25
+ itemDelayMs;
25
26
  flushing = false; // Prevent concurrent flush() calls
26
27
  constructor(extractFn, opts) {
27
28
  this.extractFn = extractFn;
28
29
  this.intervalMs = opts?.intervalMs ?? Number(process.env.PLUMB_EXTRACT_INTERVAL_MS ?? 300_000);
29
30
  this.batchSize = opts?.batchSize ?? Number(process.env.PLUMB_EXTRACT_BATCH_SIZE ?? 10);
31
+ this.itemDelayMs = opts?.itemDelayMs ?? Number(process.env.PLUMB_EXTRACT_ITEM_DELAY_MS ?? 6_500);
30
32
  }
31
33
  /**
32
34
  * Enqueue an exchange for fact extraction.
33
35
  * Triggers early flush if batch size threshold is reached.
36
+ * T-079: Added sourceChunkId parameter to link extracted facts back to raw_log chunk.
34
37
  */
35
- enqueue(exchange, userId) {
36
- this.queue.push({ exchange, userId });
38
+ enqueue(exchange, userId, sourceChunkId) {
39
+ this.queue.push({ exchange, userId, sourceChunkId });
37
40
  if (this.queue.length >= this.batchSize) {
38
41
  void this.flush();
39
42
  }
@@ -62,6 +65,7 @@ export class ExtractionQueue {
62
65
  * Flush the queue immediately: drain all pending items and call extractFn for each.
63
66
  * Uses Promise.allSettled() so one failed extraction doesn't drop others.
64
67
  * Safe to call concurrently — only one flush runs at a time.
68
+ * T-079: Pass sourceChunkId to extractFn for processing state machine.
65
69
  */
66
70
  async flush() {
67
71
  // Prevent concurrent flush() calls
@@ -73,8 +77,21 @@ export class ExtractionQueue {
73
77
  const batch = this.queue.splice(0);
74
78
  if (batch.length === 0)
75
79
  return;
76
- // Extract facts for each item in parallel
77
- await Promise.allSettled(batch.map(item => this.extractFn(item.exchange, item.userId)));
80
+ // Extract facts sequentially with per-item delay to respect LLM provider rate limits.
81
+ // (Gemini free tier: 10 RPM → 1 req/6s; default itemDelayMs=6500 gives safe headroom.)
82
+ // T-095: Previously used Promise.allSettled() (parallel); switched to sequential to avoid 429s.
83
+ for (const item of batch) {
84
+ try {
85
+ await this.extractFn(item.exchange, item.userId, item.sourceChunkId);
86
+ }
87
+ catch (err) {
88
+ // Log but don't abort the batch — match original Promise.allSettled() behavior
89
+ console.error('[plumb/extraction-queue] extractFn error:', err);
90
+ }
91
+ if (this.itemDelayMs > 0) {
92
+ await new Promise(r => setTimeout(r, this.itemDelayMs));
93
+ }
94
+ }
78
95
  }
79
96
  finally {
80
97
  this.flushing = false;
@@ -1 +1 @@
1
- {"version":3,"file":"extraction-queue.js","sourceRoot":"","sources":["../src/extraction-queue.ts"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,eAAe;IAQP;IAPX,KAAK,GAAgB,EAAE,CAAC;IACxB,KAAK,GAA0C,IAAI,CAAC;IAC3C,UAAU,CAAS;IACnB,SAAS,CAAS;IAC3B,QAAQ,GAAG,KAAK,CAAC,CAAC,mCAAmC;IAE7D,YACmB,SAAoB,EACrC,IAA6B;QADZ,cAAS,GAAT,SAAS,CAAW;QAGrC,IAAI,CAAC,UAAU,GAAG,IAAI,EAAE,UAAU,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,OAAO,CAAC,CAAC;QAC/F,IAAI,CAAC,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,EAAE,CAAC,CAAC;IACzF,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,QAAyB,EAAE,MAAc;QAC/C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACxC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO,CAAC,kBAAkB;QACnD,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACrE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACxB,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAK;QACT,mCAAmC;QACnC,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,CAAC;YACH,6CAA6C;YAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAE/B,0CAA0C;YAC1C,MAAM,OAAO,CAAC,UAAU,CACtB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAC9D,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACxB,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"extraction-queue.js","sourceRoot":"","sources":["../src/extraction-queue.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ import { type Fact, type MessageExchange } from './types.js';
16
16
  * but the store itself enforces the scope.
17
17
  * @param store - The MemoryStore instance to persist facts into.
18
18
  * @param llmFn - Optional LLM function to use (injectable for testing).
19
+ * @param sourceChunkId - Optional raw_log chunk ID (T-079 processing state machine).
19
20
  */
20
- export declare function extractFacts(exchange: MessageExchange, _userId: string, store: MemoryStore, llmFn?: (prompt: string) => Promise<string>): Promise<Fact[]>;
21
+ export declare function extractFacts(exchange: MessageExchange, _userId: string, store: MemoryStore, llmFn?: (prompt: string) => Promise<string>, sourceChunkId?: string): Promise<Fact[]>;
21
22
  //# sourceMappingURL=extractor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAa,KAAK,IAAI,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAmDxE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,WAAW,EAClB,KAAK,GAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAW,GACnD,OAAO,CAAC,IAAI,EAAE,CAAC,CAkCjB"}
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAa,KAAK,IAAI,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AA0JxE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,WAAW,EAClB,KAAK,GAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAW,EACpD,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,EAAE,CAAC,CAwCjB"}
package/dist/extractor.js CHANGED
@@ -2,17 +2,38 @@ import { callLLM } from './llm-client.js';
2
2
  import { DecayRate } from './types.js';
3
3
  /** Build the extraction prompt from a conversation exchange. */
4
4
  function buildExtractionPrompt(exchange) {
5
- return (`Extract facts from this conversation exchange worth remembering in future conversations.\n\n` +
5
+ return (`Extract facts from this conversation exchange worth recalling in a future session.\n\n` +
6
+ `Apply the 30-day recall test: "If I had no memory of this conversation and someone asked me about this user in 30 days, would knowing this fact help me serve them better?"\n\n` +
6
7
  `User: ${exchange.userMessage}\n` +
7
8
  `Agent: ${exchange.agentResponse}\n\n` +
9
+ `Extraction tiers (prioritize stable, durable facts):\n` +
10
+ `Tier 1 (always extract): identity, bio, stable preferences, permanent decisions, named relationships, skills/knowledge\n` +
11
+ `Tier 2 (extract if confident): project architecture decisions, tool choices, recurring workflows\n` +
12
+ `Tier 3 (skip unless explicitly significant): events, status updates, transient state, anything already tracked in a task or code\n\n` +
13
+ `Concrete examples:\n` +
14
+ `BAD (skip): "There are 2,162 pending raw_log chunks" — transient state, stale immediately\n` +
15
+ `BAD (skip): "Claude Code ran T-018 independently" — event, already in git history\n` +
16
+ `BAD (skip): "User registered plumb.run" — event, now complete\n` +
17
+ `GOOD (keep): "Clay prefers bullet lists over markdown tables" — stable preference\n` +
18
+ `GOOD (keep): "Plumb uses SQLite + WASM for local storage" — durable decision\n` +
19
+ `GOOD (keep): "Clay's address is 332 Casper Drive, Lafayette, CO 80026" — identity/bio\n\n` +
8
20
  `Rules:\n` +
9
21
  `- Output ONLY a valid JSON array. No prose, no explanation, no markdown fences.\n` +
10
22
  `- Each item: {"subject": string, "predicate": string, "object": string, "context": string, "confidence": number 0-1, "decay_rate": "slow"|"medium"|"fast"}\n` +
11
23
  `- decay_rate: slow=identity/stable prefs/decisions, medium=project context/tool choices, fast=transient state\n` +
12
- `- confidence: 0.95 for explicit statements, 0.7-0.85 for inferred\n` +
13
- `- Output [] if nothing is worth remembering\n` +
14
- `- Skip: pleasantries, small talk, transient questions, tool outputs, error messages\n` +
15
- `- Extract: decisions, preferences, facts about people/projects/systems, deadlines, named entities\n\n` +
24
+ `- confidence (calibrated — 0.95 is RARE, reserved for permanent facts):\n` +
25
+ ` * 0.95: Stable biographical/identity facts, verified permanent data\n` +
26
+ ` Example: "Clay lives at 332 Casper Drive, Lafayette, CO 80026" (permanent address)\n` +
27
+ ` * 0.85-0.90: Strong stated preferences, confirmed architectural decisions, recurring behavioral patterns\n` +
28
+ ` Example: "Clay prefers bullet lists over markdown tables" (stated preference, stable)\n` +
29
+ ` * 0.70-0.84: Inferred preferences, situational context, likely-but-not-certain facts\n` +
30
+ ` Example: "Clay seems to prefer morning standup calls" (inferred from behavior)\n` +
31
+ ` * 0.50-0.69: Speculative observations, one-time mentions, might-be-outdated\n` +
32
+ ` Example: "Clay might be considering switching to a new job" (speculative)\n` +
33
+ ` * Below 0.50: Do NOT extract — output [] instead (not worth storing)\n` +
34
+ `- Output [] liberally — it is better to extract nothing than to extract low-value facts that will pollute future retrieval.\n` +
35
+ `- Skip: pleasantries, small talk, transient questions, tool outputs, error messages, current date/time statements, agent operating instructions (what the agent should do/read/reply), session identifiers, heartbeat/cron state, facts about the agent itself (unless the agent has a permanent attribute like a name or email), events already recorded elsewhere (git commits, kanban tasks, emails), transient project state\n` +
36
+ `- Extract: identity/bio, stable preferences, permanent decisions, named relationships, skills/knowledge, project architecture (if durable), tool choices (if durable), recurring workflows\n\n` +
16
37
  `JSON array:`);
17
38
  }
18
39
  /**
@@ -38,6 +59,78 @@ function toDecayRate(raw) {
38
59
  return DecayRate.fast;
39
60
  return DecayRate.medium;
40
61
  }
62
+ /**
63
+ * Filter out ephemeral and agent-instruction facts that should not be stored.
64
+ *
65
+ * Blocks noise patterns:
66
+ * - Current time/date statements (e.g., 'Current time is Friday...')
67
+ * - Session identifiers (e.g., 'Current session is identified by...')
68
+ * - Agent operating instructions (e.g., 'Agent should reply HEARTBEAT_OK')
69
+ * - Heartbeat/cron state facts
70
+ *
71
+ * Does NOT block valid facts like:
72
+ * - 'Agent is named Terra' (permanent attribute)
73
+ * - 'Clay prefers agent to draft emails' (user preference)
74
+ */
75
+ function isNoiseFact(fact) {
76
+ const subjectLower = fact.subject.toLowerCase();
77
+ const predicateLower = fact.predicate.toLowerCase();
78
+ const objectLower = fact.object.toLowerCase();
79
+ // Block ephemeral timestamp subjects
80
+ const blockedSubjects = [
81
+ 'current time',
82
+ 'current date',
83
+ 'current session',
84
+ 'today',
85
+ "today's date",
86
+ ];
87
+ if (blockedSubjects.some(blocked => subjectLower.includes(blocked))) {
88
+ return true;
89
+ }
90
+ // Block agent imperative predicates (instructions to the agent)
91
+ const blockedPredicates = [
92
+ 'should reply',
93
+ 'must reply',
94
+ 'should read',
95
+ 'must read',
96
+ 'should not infer',
97
+ 'must not repeat',
98
+ 'should not repeat',
99
+ 'must not',
100
+ 'should not',
101
+ ];
102
+ if (blockedPredicates.some(blocked => predicateLower.includes(blocked))) {
103
+ return true;
104
+ }
105
+ // Block Agent + imperative (should/must) combinations
106
+ // BUT allow 'Agent is named X' or 'Agent has email X' (permanent attributes)
107
+ if (subjectLower === 'agent') {
108
+ // If predicate is a permanent attribute verb, allow it
109
+ const permanentPredicates = ['is named', 'has email', 'is called', 'name is', 'email is'];
110
+ const isPermanentAttribute = permanentPredicates.some(perm => predicateLower.includes(perm));
111
+ if (!isPermanentAttribute) {
112
+ // Block agent operating instructions
113
+ if (predicateLower.includes('should') || predicateLower.includes('must') ||
114
+ predicateLower.includes('needs to') || predicateLower.includes('will')) {
115
+ return true;
116
+ }
117
+ }
118
+ }
119
+ // Block date/time patterns in object field (e.g., '2026-03-06', 'Friday, March 6th, 2026')
120
+ const dateTimePattern = /\d{4}-\d{2}-\d{2}|(monday|tuesday|wednesday|thursday|friday|saturday|sunday).*\d{4}|\d{1,2}:\d{2}\s*(am|pm)/i;
121
+ if (predicateLower === 'is' && dateTimePattern.test(objectLower)) {
122
+ return true;
123
+ }
124
+ // Block session identifier patterns
125
+ if (objectLower.includes('openclaw session') || objectLower.includes('session 0x')) {
126
+ return true;
127
+ }
128
+ // Block heartbeat-related facts
129
+ if (subjectLower.includes('heartbeat') || objectLower.includes('heartbeat')) {
130
+ return true;
131
+ }
132
+ return false;
133
+ }
41
134
  /**
42
135
  * Extract facts from a conversation exchange via an LLM call.
43
136
  *
@@ -54,8 +147,9 @@ function toDecayRate(raw) {
54
147
  * but the store itself enforces the scope.
55
148
  * @param store - The MemoryStore instance to persist facts into.
56
149
  * @param llmFn - Optional LLM function to use (injectable for testing).
150
+ * @param sourceChunkId - Optional raw_log chunk ID (T-079 processing state machine).
57
151
  */
58
- export async function extractFacts(exchange, _userId, store, llmFn = callLLM) {
152
+ export async function extractFacts(exchange, _userId, store, llmFn = callLLM, sourceChunkId) {
59
153
  const prompt = buildExtractionPrompt(exchange);
60
154
  const response = await llmFn(prompt);
61
155
  let rawFacts;
@@ -68,6 +162,10 @@ export async function extractFacts(exchange, _userId, store, llmFn = callLLM) {
68
162
  }
69
163
  const facts = [];
70
164
  for (const raw of rawFacts) {
165
+ // Post-extraction noise filter: discard ephemeral facts before storing
166
+ if (isNoiseFact(raw)) {
167
+ continue;
168
+ }
71
169
  const factInput = {
72
170
  subject: String(raw.subject),
73
171
  predicate: String(raw.predicate),
@@ -81,7 +179,8 @@ export async function extractFacts(exchange, _userId, store, llmFn = callLLM) {
81
179
  };
82
180
  // Dedup: always insert as a new entry (do not update existing same subject+predicate).
83
181
  // The store always inserts; decay scoring handles which entry wins at retrieval time.
84
- const id = await store.store(factInput);
182
+ // T-079: Pass sourceChunkId to link fact back to raw_log chunk.
183
+ const id = await store.store(factInput, sourceChunkId);
85
184
  facts.push({ id, ...factInput });
86
185
  }
87
186
  return facts;
@@ -1 +1 @@
1
- {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=extractor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.test.d.ts","sourceRoot":"","sources":["../src/extractor.test.ts"],"names":[],"mappings":""}