@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.
- package/dist/context-builder.d.ts +1 -7
- package/dist/context-builder.d.ts.map +1 -1
- package/dist/context-builder.js +7 -44
- package/dist/context-builder.js.map +1 -1
- package/dist/index.d.ts +4 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -5
- package/dist/index.js.map +1 -1
- package/dist/local-store.d.ts +7 -82
- package/dist/local-store.d.ts.map +1 -1
- package/dist/local-store.js +84 -468
- package/dist/local-store.js.map +1 -1
- package/dist/read-path.d.ts +6 -23
- package/dist/read-path.d.ts.map +1 -1
- package/dist/read-path.js +9 -48
- package/dist/read-path.js.map +1 -1
- package/dist/schema.d.ts +4 -13
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +6 -73
- package/dist/schema.js.map +1 -1
- package/dist/scorer.d.ts +0 -9
- package/dist/scorer.d.ts.map +1 -1
- package/dist/scorer.js +1 -31
- package/dist/scorer.js.map +1 -1
- package/dist/store.d.ts +2 -16
- package/dist/store.d.ts.map +1 -1
- package/dist/types.d.ts +0 -25
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -6
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/dist/extraction-queue.d.ts +0 -72
- package/dist/extraction-queue.d.ts.map +0 -1
- package/dist/extraction-queue.js +0 -101
- package/dist/extraction-queue.js.map +0 -1
- package/dist/extractor.d.ts +0 -22
- package/dist/extractor.d.ts.map +0 -1
- package/dist/extractor.js +0 -188
- package/dist/extractor.js.map +0 -1
- package/dist/extractor.test.d.ts +0 -2
- package/dist/extractor.test.d.ts.map +0 -1
- package/dist/extractor.test.js +0 -158
- package/dist/extractor.test.js.map +0 -1
- package/dist/fact-search.d.ts +0 -32
- package/dist/fact-search.d.ts.map +0 -1
- package/dist/fact-search.js +0 -174
- package/dist/fact-search.js.map +0 -1
- package/dist/fact-search.test.d.ts +0 -12
- package/dist/fact-search.test.d.ts.map +0 -1
- package/dist/fact-search.test.js +0 -117
- package/dist/fact-search.test.js.map +0 -1
- package/dist/llm-client.d.ts +0 -59
- package/dist/llm-client.d.ts.map +0 -1
- package/dist/llm-client.js +0 -227
- package/dist/llm-client.js.map +0 -1
- package/dist/local-store.test.d.ts +0 -2
- package/dist/local-store.test.d.ts.map +0 -1
- package/dist/local-store.test.js +0 -146
- package/dist/local-store.test.js.map +0 -1
- package/dist/raw-log-search.test.d.ts +0 -12
- package/dist/raw-log-search.test.d.ts.map +0 -1
- package/dist/raw-log-search.test.js +0 -124
- package/dist/raw-log-search.test.js.map +0 -1
- package/dist/read-path.test.d.ts +0 -15
- package/dist/read-path.test.d.ts.map +0 -1
- package/dist/read-path.test.js +0 -393
- package/dist/read-path.test.js.map +0 -1
- package/dist/scorer.test.d.ts +0 -10
- package/dist/scorer.test.d.ts.map +0 -1
- package/dist/scorer.test.js +0 -169
- package/dist/scorer.test.js.map +0 -1
package/dist/fact-search.js
DELETED
|
@@ -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
|
package/dist/fact-search.js.map
DELETED
|
@@ -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"}
|
package/dist/fact-search.test.js
DELETED
|
@@ -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":"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"}
|
package/dist/llm-client.d.ts
DELETED
|
@@ -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
|
package/dist/llm-client.d.ts.map
DELETED
|
@@ -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"}
|
package/dist/llm-client.js
DELETED
|
@@ -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
|
package/dist/llm-client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"llm-client.js","sourceRoot":"","sources":["../src/llm-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-store.test.d.ts","sourceRoot":"","sources":["../src/local-store.test.ts"],"names":[],"mappings":""}
|