@getplumb/core 0.3.0 → 0.4.1

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 (71) hide show
  1. package/dist/context-builder.d.ts +1 -7
  2. package/dist/context-builder.d.ts.map +1 -1
  3. package/dist/context-builder.js +7 -44
  4. package/dist/context-builder.js.map +1 -1
  5. package/dist/index.d.ts +4 -10
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -5
  8. package/dist/index.js.map +1 -1
  9. package/dist/local-store.d.ts +7 -82
  10. package/dist/local-store.d.ts.map +1 -1
  11. package/dist/local-store.js +84 -468
  12. package/dist/local-store.js.map +1 -1
  13. package/dist/read-path.d.ts +6 -23
  14. package/dist/read-path.d.ts.map +1 -1
  15. package/dist/read-path.js +9 -48
  16. package/dist/read-path.js.map +1 -1
  17. package/dist/schema.d.ts +4 -13
  18. package/dist/schema.d.ts.map +1 -1
  19. package/dist/schema.js +6 -73
  20. package/dist/schema.js.map +1 -1
  21. package/dist/scorer.d.ts +0 -9
  22. package/dist/scorer.d.ts.map +1 -1
  23. package/dist/scorer.js +1 -31
  24. package/dist/scorer.js.map +1 -1
  25. package/dist/store.d.ts +2 -16
  26. package/dist/store.d.ts.map +1 -1
  27. package/dist/types.d.ts +0 -25
  28. package/dist/types.d.ts.map +1 -1
  29. package/dist/types.js +1 -6
  30. package/dist/types.js.map +1 -1
  31. package/package.json +1 -1
  32. package/dist/extraction-queue.d.ts +0 -72
  33. package/dist/extraction-queue.d.ts.map +0 -1
  34. package/dist/extraction-queue.js +0 -101
  35. package/dist/extraction-queue.js.map +0 -1
  36. package/dist/extractor.d.ts +0 -22
  37. package/dist/extractor.d.ts.map +0 -1
  38. package/dist/extractor.js +0 -188
  39. package/dist/extractor.js.map +0 -1
  40. package/dist/extractor.test.d.ts +0 -2
  41. package/dist/extractor.test.d.ts.map +0 -1
  42. package/dist/extractor.test.js +0 -158
  43. package/dist/extractor.test.js.map +0 -1
  44. package/dist/fact-search.d.ts +0 -32
  45. package/dist/fact-search.d.ts.map +0 -1
  46. package/dist/fact-search.js +0 -174
  47. package/dist/fact-search.js.map +0 -1
  48. package/dist/fact-search.test.d.ts +0 -12
  49. package/dist/fact-search.test.d.ts.map +0 -1
  50. package/dist/fact-search.test.js +0 -117
  51. package/dist/fact-search.test.js.map +0 -1
  52. package/dist/llm-client.d.ts +0 -59
  53. package/dist/llm-client.d.ts.map +0 -1
  54. package/dist/llm-client.js +0 -227
  55. package/dist/llm-client.js.map +0 -1
  56. package/dist/local-store.test.d.ts +0 -2
  57. package/dist/local-store.test.d.ts.map +0 -1
  58. package/dist/local-store.test.js +0 -146
  59. package/dist/local-store.test.js.map +0 -1
  60. package/dist/raw-log-search.test.d.ts +0 -12
  61. package/dist/raw-log-search.test.d.ts.map +0 -1
  62. package/dist/raw-log-search.test.js +0 -124
  63. package/dist/raw-log-search.test.js.map +0 -1
  64. package/dist/read-path.test.d.ts +0 -15
  65. package/dist/read-path.test.d.ts.map +0 -1
  66. package/dist/read-path.test.js +0 -393
  67. package/dist/read-path.test.js.map +0 -1
  68. package/dist/scorer.test.d.ts +0 -10
  69. package/dist/scorer.test.d.ts.map +0 -1
  70. package/dist/scorer.test.js +0 -169
  71. package/dist/scorer.test.js.map +0 -1
@@ -1,174 +0,0 @@
1
- /**
2
- * Fact hybrid search (Layer 2 retrieval).
3
- *
4
- * Pipeline:
5
- * 1. BM25 keyword search over concatenated fact text (subject+predicate+object+context)
6
- * 2. KNN vector search via JS cosine similarity (replaces sqlite-vec)
7
- * 3. Reciprocal Rank Fusion (RRF, k=60) merges both ranked lists
8
- * 4. Recency decay: score *= e^(-lambda × age_in_days), using per-fact decay_rate
9
- * 5. Cross-encoder reranker (top-20 candidates → Xenova/ms-marco-MiniLM-L-6-v2)
10
- * 6. Return top-k by reranker score (falls back to RRF×decay if reranker fails)
11
- *
12
- * Decay lambdas by fact decay_rate:
13
- * slow=0.003 (half-life ~231 days) — identity, stable preferences
14
- * medium=0.012 (half-life ~58 days) — project context, tool choices
15
- * fast=0.05 (half-life ~14 days) — transient state
16
- */
17
- import { Bm25 } from './bm25.js';
18
- import { embedQuery, rerankScores } from './embedder.js';
19
- import { knnSearch, deserializeEmbedding } from './vector-search.js';
20
- // RRF constant (standard k=60).
21
- const RRF_K = 60;
22
- // Number of candidates passed to the cross-encoder.
23
- const RERANK_TOP_K = 20;
24
- // Decay lambdas by fact decay_rate field.
25
- const DECAY_LAMBDAS = {
26
- slow: 0.003,
27
- medium: 0.012,
28
- fast: 0.05,
29
- };
30
- // ─── Helpers ──────────────────────────────────────────────────────────────────
31
- function factText(row) {
32
- return `${row.subject} ${row.predicate} ${row.object} ${row.context ?? ''}`.trim();
33
- }
34
- function ageInDays(timestamp) {
35
- return (Date.now() - new Date(timestamp).getTime()) / (1_000 * 60 * 60 * 24);
36
- }
37
- function recencyDecay(timestamp, decayRate) {
38
- const lambda = DECAY_LAMBDAS[decayRate] ?? DECAY_LAMBDAS.medium;
39
- return Math.exp(-lambda * ageInDays(timestamp));
40
- }
41
- function rowToFact(row) {
42
- return {
43
- id: row.id,
44
- subject: row.subject,
45
- predicate: row.predicate,
46
- object: row.object,
47
- confidence: row.confidence,
48
- decayRate: row.decay_rate,
49
- timestamp: new Date(row.timestamp),
50
- sourceSessionId: row.source_session_id,
51
- ...(row.source_session_label !== null ? { sourceSessionLabel: row.source_session_label } : {}),
52
- ...(row.context !== null ? { context: row.context } : {}),
53
- };
54
- }
55
- /**
56
- * Merge two ranked lists via Reciprocal Rank Fusion.
57
- */
58
- function rrf(vecRanked, bm25Ranked) {
59
- const scores = new Map();
60
- for (let rank = 0; rank < vecRanked.length; rank++) {
61
- const id = vecRanked[rank]?.[0];
62
- if (id === undefined)
63
- continue;
64
- scores.set(id, (scores.get(id) ?? 0) + 1 / (RRF_K + rank + 1));
65
- }
66
- for (let rank = 0; rank < bm25Ranked.length; rank++) {
67
- const id = bm25Ranked[rank]?.[0];
68
- if (id === undefined)
69
- continue;
70
- scores.set(id, (scores.get(id) ?? 0) + 1 / (RRF_K + rank + 1));
71
- }
72
- return scores;
73
- }
74
- // ─── Public API ───────────────────────────────────────────────────────────────
75
- /**
76
- * Hybrid search over facts.
77
- *
78
- * @param db The WASM SQLite Database instance
79
- * @param userId Scopes the search to this user's data
80
- * @param query Natural language query string
81
- * @param limit Number of results to return (default 20)
82
- * @param preloadedCorpus Optional pre-loaded vec_facts corpus (T-096: in-memory cache)
83
- */
84
- export async function searchFacts(db, userId, query, limit = 20, preloadedCorpus) {
85
- // ── 1. Fetch all non-deleted fact rows for this user ────────────────────
86
- const stmt = db.prepare(`SELECT id, user_id, subject, predicate, object, confidence,
87
- decay_rate, timestamp, source_session_id, source_session_label,
88
- context, deleted_at, vec_rowid
89
- FROM facts
90
- WHERE user_id = ? AND deleted_at IS NULL AND confidence >= 0.65
91
- ORDER BY timestamp DESC`);
92
- stmt.bind([userId]);
93
- const allRows = [];
94
- while (stmt.step()) {
95
- allRows.push(stmt.get({}));
96
- }
97
- stmt.finalize();
98
- if (allRows.length === 0)
99
- return [];
100
- const idToRow = new Map(allRows.map((r) => [r.id, r]));
101
- // ── 2. BM25 search ───────────────────────────────────────────────────────
102
- const corpus = allRows.map(factText);
103
- const bm25 = new Bm25(corpus);
104
- const bm25RawScores = bm25.scores(query);
105
- const bm25Ranked = allRows
106
- .map((r, i) => [r.id, bm25RawScores[i] ?? 0])
107
- .sort((a, b) => b[1] - a[1]);
108
- // ── 3. Vector search via JS cosine similarity ───────────────────────────
109
- const queryVec = await embedQuery(query);
110
- // T-096: Use preloaded corpus if provided, otherwise fetch from vec_facts
111
- let vecCorpus;
112
- if (preloadedCorpus !== undefined) {
113
- // Map rowid → id for knnSearch compatibility
114
- vecCorpus = preloadedCorpus.map(entry => ({ id: entry.rowid, embedding: entry.embedding }));
115
- }
116
- else {
117
- // Fetch all embeddings from vec_facts (legacy path, used if cache not provided)
118
- const vecStmt = db.prepare(`SELECT id, embedding FROM vec_facts`);
119
- vecCorpus = [];
120
- while (vecStmt.step()) {
121
- const row = vecStmt.get({});
122
- vecCorpus.push({
123
- id: row.id,
124
- embedding: deserializeEmbedding(row.embedding),
125
- });
126
- }
127
- vecStmt.finalize();
128
- }
129
- // Perform KNN search
130
- const vecFetchLimit = Math.min(allRows.length, Math.max(RERANK_TOP_K * 2, limit * 3, 50));
131
- const vecResults = knnSearch(queryVec, vecCorpus, vecFetchLimit);
132
- // Map vec_facts ids back to fact ids
133
- const vecRanked = [];
134
- for (const vecResult of vecResults) {
135
- const factRow = allRows.find((r) => r.vec_rowid === vecResult.id);
136
- if (factRow !== undefined) {
137
- vecRanked.push([factRow.id, 1 - vecResult.distance]);
138
- }
139
- }
140
- // ── 4. RRF merge ────────────────────────────────────────────────────────
141
- const rrfScores = rrf(vecRanked, bm25Ranked);
142
- // ── 5. Recency decay (per-fact lambda) ──────────────────────────────────
143
- const decayedScores = [];
144
- for (const [id, rrfScore] of rrfScores) {
145
- const row = idToRow.get(id);
146
- if (row === undefined)
147
- continue;
148
- const decay = recencyDecay(row.timestamp, row.decay_rate);
149
- decayedScores.push([id, rrfScore * decay]);
150
- }
151
- decayedScores.sort((a, b) => b[1] - a[1]);
152
- // ── 6. Take top candidates for reranking ────────────────────────────────
153
- const candidates = decayedScores.slice(0, Math.max(RERANK_TOP_K, limit));
154
- // ── 7. Cross-encoder reranking ──────────────────────────────────────────
155
- const passages = candidates.map(([id]) => factText(idToRow.get(id)));
156
- const rerankerScores = await rerankScores(query, passages);
157
- const hasRerankerSignal = rerankerScores.some((s) => s !== 0);
158
- const ranked = candidates.map(([id, rrfDecayScore], i) => ({
159
- id,
160
- finalScore: hasRerankerSignal ? (rerankerScores[i] ?? 0) : rrfDecayScore,
161
- }));
162
- ranked.sort((a, b) => b.finalScore - a.finalScore);
163
- // ── 8. Build output ─────────────────────────────────────────────────────
164
- return ranked.slice(0, limit).map(({ id, finalScore }) => {
165
- const row = idToRow.get(id);
166
- const fact = rowToFact(row);
167
- return {
168
- fact,
169
- score: finalScore,
170
- ageInDays: ageInDays(row.timestamp),
171
- };
172
- });
173
- }
174
- //# sourceMappingURL=fact-search.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fact-search.js","sourceRoot":"","sources":["../src/fact-search.ts"],"names":[],"mappings":"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"}
@@ -1,12 +0,0 @@
1
- /**
2
- * Tests for Layer 2 hybrid search (fact-search.ts).
3
- *
4
- * Stores 3 facts with distinct topics via store.store(), then verifies that
5
- * search() returns ranked results with the expected structure.
6
- *
7
- * Note: The first test run downloads the BAAI/bge-small-en-v1.5 embedding model
8
- * (~100 MB) and the ms-marco cross-encoder (~50 MB) — subsequent runs use the
9
- * local ~/.cache/huggingface/ cache.
10
- */
11
- export {};
12
- //# sourceMappingURL=fact-search.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fact-search.test.d.ts","sourceRoot":"","sources":["../src/fact-search.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -1,117 +0,0 @@
1
- /**
2
- * Tests for Layer 2 hybrid search (fact-search.ts).
3
- *
4
- * Stores 3 facts with distinct topics via store.store(), then verifies that
5
- * search() returns ranked results with the expected structure.
6
- *
7
- * Note: The first test run downloads the BAAI/bge-small-en-v1.5 embedding model
8
- * (~100 MB) and the ms-marco cross-encoder (~50 MB) — subsequent runs use the
9
- * local ~/.cache/huggingface/ cache.
10
- */
11
- import { test, after } from 'node:test';
12
- import assert from 'node:assert/strict';
13
- import { tmpdir } from 'node:os';
14
- import { join } from 'node:path';
15
- import { rmSync } from 'node:fs';
16
- import { LocalStore } from './local-store.js';
17
- import { DecayRate } from './types.js';
18
- const dbPath = join(tmpdir(), `plumb-fact-search-test-${Date.now()}.db`);
19
- const store = new LocalStore({ dbPath, userId: 'fact-search-test-user' });
20
- after(() => {
21
- store.close();
22
- rmSync(dbPath, { force: true });
23
- });
24
- // ─── Fixtures ────────────────────────────────────────────────────────────────
25
- const FACTS = [
26
- {
27
- subject: 'Clay',
28
- predicate: 'is actively searching for',
29
- object: 'software engineering jobs',
30
- context: 'Clay is looking at Samsara, applied to multiple companies, tracking applications and interviews',
31
- confidence: 0.95,
32
- decayRate: DecayRate.slow,
33
- timestamp: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000), // 1 day ago
34
- sourceSessionId: 'session-job-search',
35
- sourceSessionLabel: 'job-search-chat',
36
- },
37
- {
38
- subject: 'Clay',
39
- predicate: 'prefers',
40
- object: 'TypeScript over JavaScript',
41
- context: 'Clay mentioned preferring strict typing and has all projects configured with strict mode',
42
- confidence: 0.9,
43
- decayRate: DecayRate.slow,
44
- timestamp: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000), // 5 days ago
45
- sourceSessionId: 'session-ts-prefs',
46
- sourceSessionLabel: 'typescript-chat',
47
- },
48
- {
49
- subject: 'chocolate cake recipe',
50
- predicate: 'requires',
51
- object: '200g butter and 50g cocoa powder',
52
- context: 'Classic recipe baked at 180 degrees for 30 minutes with ganache frosting',
53
- confidence: 0.85,
54
- decayRate: DecayRate.fast,
55
- timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000), // 2 days ago
56
- sourceSessionId: 'session-cooking',
57
- sourceSessionLabel: 'cooking-chat',
58
- },
59
- ];
60
- // ─── Store facts (shared setup) ──────────────────────────────────────────────
61
- test('store 3 facts with distinct topics', { timeout: 120_000 }, async () => {
62
- for (const fact of FACTS) {
63
- const id = await store.store(fact);
64
- assert.match(id, /^[0-9a-f-]{36}$/, 'id should be a UUID');
65
- }
66
- const status = await store.status();
67
- assert.equal(status.factCount, 3, 'all 3 facts should be stored');
68
- });
69
- // ─── Search ──────────────────────────────────────────────────────────────────
70
- test('search returns results with required SearchResult fields', { timeout: 120_000 }, async () => {
71
- const results = await store.search('job search applications', 3);
72
- assert.ok(results.length > 0, 'should return at least one result');
73
- for (const r of results) {
74
- assert.ok(typeof r.fact.id === 'string', 'fact.id must be a string');
75
- assert.ok(typeof r.fact.subject === 'string', 'fact.subject must be a string');
76
- assert.ok(typeof r.fact.predicate === 'string', 'fact.predicate must be a string');
77
- assert.ok(typeof r.fact.object === 'string', 'fact.object must be a string');
78
- assert.ok(typeof r.score === 'number', 'score must be a number');
79
- assert.ok(typeof r.ageInDays === 'number', 'ageInDays must be a number');
80
- assert.ok(r.fact.timestamp instanceof Date, 'timestamp must be a Date');
81
- }
82
- });
83
- test('search ranks job-search fact first for job query', { timeout: 120_000 }, async () => {
84
- const results = await store.search('job search applications Samsara', 3);
85
- assert.ok(results.length > 0, 'should return results');
86
- const top = results[0];
87
- assert.ok(top !== undefined, 'should have a top result');
88
- // The job-search fact should rank first.
89
- assert.equal(top.fact.subject, 'Clay', 'top result subject should be Clay');
90
- assert.ok(top.fact.object.includes('job') || top.fact.object.includes('engineering'), 'top result should be about job search');
91
- });
92
- test('search returns cooking fact in results for recipe query', { timeout: 120_000 }, async () => {
93
- const results = await store.search('chocolate cake recipe baking', 3);
94
- assert.ok(results.length > 0, 'should return results');
95
- const cookingResult = results.find((r) => r.fact.sourceSessionId === 'session-cooking');
96
- assert.ok(cookingResult !== undefined, 'cooking fact should appear in results');
97
- });
98
- test('search returns empty array when no facts exist', { timeout: 30_000 }, async () => {
99
- const emptyStore = new LocalStore({
100
- dbPath: join(tmpdir(), `plumb-fact-empty-${Date.now()}.db`),
101
- userId: 'empty-user',
102
- });
103
- try {
104
- const results = await emptyStore.search('anything', 5);
105
- assert.deepEqual(results, []);
106
- }
107
- finally {
108
- emptyStore.close();
109
- }
110
- });
111
- test('benchmark smoke: job search query returns at least 1 result with correct subject', { timeout: 120_000 }, async () => {
112
- const results = await store.search('job search applications', 5);
113
- assert.ok(results.length >= 1, 'should return at least 1 result');
114
- const jobResult = results.find((r) => r.fact.subject === 'Clay' && r.fact.object.includes('job'));
115
- assert.ok(jobResult !== undefined, 'should find Clay job search fact');
116
- });
117
- //# sourceMappingURL=fact-search.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fact-search.test.js","sourceRoot":"","sources":["../src/fact-search.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,0BAA0B,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACzE,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAE1E,KAAK,CAAC,GAAG,EAAE;IACT,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,gFAAgF;AAEhF,MAAM,KAAK,GAAG;IACZ;QACE,OAAO,EAAE,MAAM;QACf,SAAS,EAAE,2BAA2B;QACtC,MAAM,EAAE,2BAA2B;QACnC,OAAO,EAAE,iGAAiG;QAC1G,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,SAAS,CAAC,IAAI;QACzB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,YAAY;QACvE,eAAe,EAAE,oBAAoB;QACrC,kBAAkB,EAAE,iBAAiB;KACtC;IACD;QACE,OAAO,EAAE,MAAM;QACf,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,4BAA4B;QACpC,OAAO,EAAE,0FAA0F;QACnG,UAAU,EAAE,GAAG;QACf,SAAS,EAAE,SAAS,CAAC,IAAI;QACzB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,aAAa;QACxE,eAAe,EAAE,kBAAkB;QACnC,kBAAkB,EAAE,iBAAiB;KACtC;IACD;QACE,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,UAAU;QACrB,MAAM,EAAE,kCAAkC;QAC1C,OAAO,EAAE,0EAA0E;QACnF,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,SAAS,CAAC,IAAI;QACzB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,aAAa;QACxE,eAAe,EAAE,iBAAiB;QAClC,kBAAkB,EAAE,cAAc;KACnC;CACF,CAAC;AAEF,gFAAgF;AAEhF,IAAI,CAAC,oCAAoC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE;IAC1E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,iBAAiB,EAAE,qBAAqB,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;IACpC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,8BAA8B,CAAC,CAAC;AACpE,CAAC,CAAC,CAAC;AAEH,gFAAgF;AAEhF,IAAI,CAAC,0DAA0D,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE;IAChG,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC;IAEjE,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,mCAAmC,CAAC,CAAC;IAEnE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,QAAQ,EAAE,0BAA0B,CAAC,CAAC;QACrE,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,+BAA+B,CAAC,CAAC;QAC/E,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,iCAAiC,CAAC,CAAC;QACnF,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,8BAA8B,CAAC,CAAC;QAC7E,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE,wBAAwB,CAAC,CAAC;QACjE,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,4BAA4B,CAAC,CAAC;QACzE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,YAAY,IAAI,EAAE,0BAA0B,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kDAAkD,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE;IACxF,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,iCAAiC,EAAE,CAAC,CAAC,CAAC;IAEzE,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,uBAAuB,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,SAAS,EAAE,0BAA0B,CAAC,CAAC;IAEzD,yCAAyC;IACzC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,mCAAmC,CAAC,CAAC;IAC5E,MAAM,CAAC,EAAE,CACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,EAC1E,uCAAuC,CACxC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yDAAyD,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE;IAC/F,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC;IAEtE,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,uBAAuB,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,KAAK,iBAAiB,CAAC,CAAC;IACxF,MAAM,CAAC,EAAE,CAAC,aAAa,KAAK,SAAS,EAAE,uCAAuC,CAAC,CAAC;AAClF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gDAAgD,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,IAAI,EAAE;IACrF,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC;QAChC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,oBAAoB,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC;QAC3D,MAAM,EAAE,YAAY;KACrB,CAAC,CAAC;IACH,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kFAAkF,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE;IACxH,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC;IACjE,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,iCAAiC,CAAC,CAAC;IAElE,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAC5B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAClE,CAAC;IACF,MAAM,CAAC,EAAE,CAAC,SAAS,KAAK,SAAS,EAAE,kCAAkC,CAAC,CAAC;AACzE,CAAC,CAAC,CAAC"}
@@ -1,59 +0,0 @@
1
- /**
2
- * LLM configuration that can be passed directly instead of relying on environment variables.
3
- * When provided, these values take precedence over env vars.
4
- */
5
- export interface LLMConfig {
6
- /** Provider: 'google' (recommended) | 'openai' | 'anthropic' | 'ollama' | 'openai-compatible'. Defaults to 'openai'. */
7
- provider?: string;
8
- /** Model ID. Defaults to provider-specific default. */
9
- model?: string;
10
- /** API key. Takes precedence over env var for the given provider. */
11
- apiKey?: string;
12
- /** Base URL for 'openai-compatible' or 'ollama' providers. */
13
- baseUrl?: string;
14
- }
15
- /**
16
- * Resolve the OpenAI API key from environment variables.
17
- * Returns the key if found, otherwise throws a clear error.
18
- *
19
- * Set OPENAI_API_KEY in your environment before using Plumb with the OpenAI provider.
20
- *
21
- * @throws Error if no key is found
22
- */
23
- export declare function resolveOpenAIKey(): string;
24
- /**
25
- * Resolve the Anthropic API key from environment variables.
26
- * Returns the key if found, otherwise throws a clear error.
27
- *
28
- * Set ANTHROPIC_API_KEY in your environment before using Plumb with the Anthropic provider.
29
- *
30
- * @throws Error if no key is found
31
- */
32
- export declare function resolveAnthropicKey(): string;
33
- /**
34
- * Resolve the Gemini API key from environment variables.
35
- * Returns the key if found, otherwise throws a clear error.
36
- *
37
- * Set GEMINI_API_KEY in your environment before using Plumb with the Google provider.
38
- *
39
- * @throws Error if no key is found
40
- */
41
- export declare function resolveGeminiKey(): string;
42
- /**
43
- * Calls the configured LLM with the given prompt and returns the text response.
44
- * Provider and model are configurable via env:
45
- * PLUMB_LLM_PROVIDER — 'openai' (default), 'anthropic', 'ollama', 'openai-compatible', 'google'
46
- * PLUMB_LLM_MODEL — model ID, defaults vary per provider
47
- * PLUMB_LLM_BASE_URL — for 'openai-compatible' provider
48
- * OLLAMA_HOST — for 'ollama' provider (default: http://localhost:11434/v1)
49
- */
50
- export declare function callLLM(prompt: string): Promise<string>;
51
- /**
52
- * Calls the LLM using explicitly provided config rather than environment variables.
53
- * Falls back to env vars for any values not provided in config.
54
- *
55
- * Use this when you want to pass LLM credentials programmatically (e.g. from plugin config)
56
- * without mutating process.env.
57
- */
58
- export declare function callLLMWithConfig(prompt: string, config: LLMConfig): Promise<string>;
59
- //# sourceMappingURL=llm-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"llm-client.d.ts","sourceRoot":"","sources":["../src/llm-client.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,wHAAwH;IACxH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAQzC;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAQ5C;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAQzC;AAED;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA2F7D;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAoF1F"}
@@ -1,227 +0,0 @@
1
- import OpenAI from 'openai';
2
- /**
3
- * Default models per provider
4
- * Recommended: google/gemini-2.5-flash-lite (extremely cheap and fast)
5
- */
6
- const DEFAULT_MODELS = {
7
- google: 'gemini-2.5-flash-lite',
8
- openai: 'gpt-4o-mini',
9
- anthropic: 'claude-haiku-4-5-20251001',
10
- ollama: 'llama3.1',
11
- 'openai-compatible': 'gpt-4o-mini',
12
- };
13
- /**
14
- * Resolve the OpenAI API key from environment variables.
15
- * Returns the key if found, otherwise throws a clear error.
16
- *
17
- * Set OPENAI_API_KEY in your environment before using Plumb with the OpenAI provider.
18
- *
19
- * @throws Error if no key is found
20
- */
21
- export function resolveOpenAIKey() {
22
- const envKey = process.env['OPENAI_API_KEY'];
23
- if (envKey)
24
- return envKey;
25
- throw new Error('Plumb fact extraction requires OPENAI_API_KEY. ' +
26
- 'Set the OPENAI_API_KEY environment variable and try again.');
27
- }
28
- /**
29
- * Resolve the Anthropic API key from environment variables.
30
- * Returns the key if found, otherwise throws a clear error.
31
- *
32
- * Set ANTHROPIC_API_KEY in your environment before using Plumb with the Anthropic provider.
33
- *
34
- * @throws Error if no key is found
35
- */
36
- export function resolveAnthropicKey() {
37
- const envKey = process.env['ANTHROPIC_API_KEY'];
38
- if (envKey)
39
- return envKey;
40
- throw new Error('Plumb fact extraction requires ANTHROPIC_API_KEY. ' +
41
- 'Set the ANTHROPIC_API_KEY environment variable and try again.');
42
- }
43
- /**
44
- * Resolve the Gemini API key from environment variables.
45
- * Returns the key if found, otherwise throws a clear error.
46
- *
47
- * Set GEMINI_API_KEY in your environment before using Plumb with the Google provider.
48
- *
49
- * @throws Error if no key is found
50
- */
51
- export function resolveGeminiKey() {
52
- const envKey = process.env['GEMINI_API_KEY'];
53
- if (envKey)
54
- return envKey;
55
- throw new Error('Plumb fact extraction requires GEMINI_API_KEY. ' +
56
- 'Set the GEMINI_API_KEY environment variable and try again.');
57
- }
58
- /**
59
- * Calls the configured LLM with the given prompt and returns the text response.
60
- * Provider and model are configurable via env:
61
- * PLUMB_LLM_PROVIDER — 'openai' (default), 'anthropic', 'ollama', 'openai-compatible', 'google'
62
- * PLUMB_LLM_MODEL — model ID, defaults vary per provider
63
- * PLUMB_LLM_BASE_URL — for 'openai-compatible' provider
64
- * OLLAMA_HOST — for 'ollama' provider (default: http://localhost:11434/v1)
65
- */
66
- export async function callLLM(prompt) {
67
- const provider = process.env['PLUMB_LLM_PROVIDER'] ?? 'openai';
68
- const model = process.env['PLUMB_LLM_MODEL'] ?? DEFAULT_MODELS[provider] ?? 'gpt-4o-mini';
69
- if (provider === 'openai') {
70
- const apiKey = resolveOpenAIKey();
71
- const client = new OpenAI({ apiKey });
72
- const response = await client.chat.completions.create({
73
- model,
74
- messages: [{ role: 'user', content: prompt }],
75
- max_tokens: 4096,
76
- });
77
- return response.choices[0]?.message?.content ?? '';
78
- }
79
- if (provider === 'anthropic') {
80
- // Dynamic import to handle optional dependency
81
- let Anthropic;
82
- try {
83
- Anthropic = (await import('@anthropic-ai/sdk')).default;
84
- }
85
- catch {
86
- throw new Error('Anthropic provider requires @anthropic-ai/sdk. Install it with: npm install @anthropic-ai/sdk');
87
- }
88
- const apiKey = resolveAnthropicKey();
89
- const client = new Anthropic({ apiKey });
90
- const message = await client.messages.create({
91
- model,
92
- max_tokens: 4096,
93
- messages: [{ role: 'user', content: prompt }],
94
- });
95
- const block = message.content[0];
96
- if (block === undefined || block.type !== 'text') {
97
- throw new Error('Unexpected response type from Anthropic LLM');
98
- }
99
- return block.text;
100
- }
101
- if (provider === 'ollama') {
102
- // Ollama provides an OpenAI-compatible API
103
- const baseURL = process.env['OLLAMA_HOST'] ?? 'http://localhost:11434/v1';
104
- const client = new OpenAI({
105
- baseURL,
106
- apiKey: 'ollama', // Required by openai package but ignored by Ollama
107
- });
108
- const response = await client.chat.completions.create({
109
- model,
110
- messages: [{ role: 'user', content: prompt }],
111
- max_tokens: 4096,
112
- });
113
- return response.choices[0]?.message?.content ?? '';
114
- }
115
- if (provider === 'google') {
116
- // Google Gemini via OpenAI-compatible endpoint
117
- const apiKey = resolveGeminiKey();
118
- const client = new OpenAI({
119
- baseURL: 'https://generativelanguage.googleapis.com/v1beta/openai',
120
- apiKey,
121
- });
122
- const response = await client.chat.completions.create({
123
- model,
124
- messages: [{ role: 'user', content: prompt }],
125
- max_tokens: 4096,
126
- });
127
- return response.choices[0]?.message?.content ?? '';
128
- }
129
- if (provider === 'openai-compatible') {
130
- const baseURL = process.env['PLUMB_LLM_BASE_URL'];
131
- if (!baseURL) {
132
- throw new Error('PLUMB_LLM_BASE_URL is required for openai-compatible provider. ' +
133
- 'Example: export PLUMB_LLM_BASE_URL=https://api.together.xyz/v1');
134
- }
135
- const apiKey = resolveOpenAIKey();
136
- const client = new OpenAI({ baseURL, apiKey });
137
- const response = await client.chat.completions.create({
138
- model,
139
- messages: [{ role: 'user', content: prompt }],
140
- max_tokens: 4096,
141
- });
142
- return response.choices[0]?.message?.content ?? '';
143
- }
144
- throw new Error(`Unsupported PLUMB_LLM_PROVIDER: ${provider}. Supported: openai, anthropic, ollama, google, openai-compatible`);
145
- }
146
- /**
147
- * Calls the LLM using explicitly provided config rather than environment variables.
148
- * Falls back to env vars for any values not provided in config.
149
- *
150
- * Use this when you want to pass LLM credentials programmatically (e.g. from plugin config)
151
- * without mutating process.env.
152
- */
153
- export async function callLLMWithConfig(prompt, config) {
154
- const provider = config.provider ?? process.env['PLUMB_LLM_PROVIDER'] ?? 'openai';
155
- const model = config.model ?? process.env['PLUMB_LLM_MODEL'] ?? DEFAULT_MODELS[provider] ?? 'gpt-4o-mini';
156
- if (provider === 'openai') {
157
- const apiKey = config.apiKey ?? resolveOpenAIKey();
158
- const client = new OpenAI({ apiKey });
159
- const response = await client.chat.completions.create({
160
- model,
161
- messages: [{ role: 'user', content: prompt }],
162
- max_tokens: 4096,
163
- });
164
- return response.choices[0]?.message?.content ?? '';
165
- }
166
- if (provider === 'anthropic') {
167
- let Anthropic;
168
- try {
169
- Anthropic = (await import('@anthropic-ai/sdk')).default;
170
- }
171
- catch {
172
- throw new Error('Anthropic provider requires @anthropic-ai/sdk. Install it with: npm install @anthropic-ai/sdk');
173
- }
174
- const apiKey = config.apiKey ?? resolveAnthropicKey();
175
- const client = new Anthropic({ apiKey });
176
- const message = await client.messages.create({
177
- model,
178
- max_tokens: 4096,
179
- messages: [{ role: 'user', content: prompt }],
180
- });
181
- const block = message.content[0];
182
- if (block === undefined || block.type !== 'text') {
183
- throw new Error('Unexpected response type from Anthropic LLM');
184
- }
185
- return block.text;
186
- }
187
- if (provider === 'ollama') {
188
- const baseURL = config.baseUrl ?? process.env['OLLAMA_HOST'] ?? 'http://localhost:11434/v1';
189
- const client = new OpenAI({ baseURL, apiKey: 'ollama' });
190
- const response = await client.chat.completions.create({
191
- model,
192
- messages: [{ role: 'user', content: prompt }],
193
- max_tokens: 4096,
194
- });
195
- return response.choices[0]?.message?.content ?? '';
196
- }
197
- if (provider === 'google') {
198
- const apiKey = config.apiKey ?? resolveGeminiKey();
199
- const client = new OpenAI({
200
- baseURL: 'https://generativelanguage.googleapis.com/v1beta/openai',
201
- apiKey,
202
- });
203
- const response = await client.chat.completions.create({
204
- model,
205
- messages: [{ role: 'user', content: prompt }],
206
- max_tokens: 4096,
207
- });
208
- return response.choices[0]?.message?.content ?? '';
209
- }
210
- if (provider === 'openai-compatible') {
211
- const baseURL = config.baseUrl ?? process.env['PLUMB_LLM_BASE_URL'];
212
- if (!baseURL) {
213
- throw new Error('PLUMB_LLM_BASE_URL is required for openai-compatible provider. ' +
214
- 'Example: export PLUMB_LLM_BASE_URL=https://api.together.xyz/v1');
215
- }
216
- const apiKey = config.apiKey ?? resolveOpenAIKey();
217
- const client = new OpenAI({ baseURL, apiKey });
218
- const response = await client.chat.completions.create({
219
- model,
220
- messages: [{ role: 'user', content: prompt }],
221
- max_tokens: 4096,
222
- });
223
- return response.choices[0]?.message?.content ?? '';
224
- }
225
- throw new Error(`Unsupported provider: ${provider}. Supported: openai, anthropic, ollama, google, openai-compatible`);
226
- }
227
- //# sourceMappingURL=llm-client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"llm-client.js","sourceRoot":"","sources":["../src/llm-client.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=local-store.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"local-store.test.d.ts","sourceRoot":"","sources":["../src/local-store.test.ts"],"names":[],"mappings":""}