@indigoai-us/cq 0.0.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/__tests__/integration.test.d.ts +8 -0
- package/dist/__tests__/integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration.test.js +233 -0
- package/dist/__tests__/integration.test.js.map +1 -0
- package/dist/budget/__tests__/budget.test.d.ts +2 -0
- package/dist/budget/__tests__/budget.test.d.ts.map +1 -0
- package/dist/budget/__tests__/budget.test.js +238 -0
- package/dist/budget/__tests__/budget.test.js.map +1 -0
- package/dist/budget/__tests__/token-tracker.test.d.ts +2 -0
- package/dist/budget/__tests__/token-tracker.test.d.ts.map +1 -0
- package/dist/budget/__tests__/token-tracker.test.js +292 -0
- package/dist/budget/__tests__/token-tracker.test.js.map +1 -0
- package/dist/budget/index.d.ts +38 -0
- package/dist/budget/index.d.ts.map +1 -0
- package/dist/budget/index.js +192 -0
- package/dist/budget/index.js.map +1 -0
- package/dist/budget/token-tracker.d.ts +62 -0
- package/dist/budget/token-tracker.d.ts.map +1 -0
- package/dist/budget/token-tracker.js +152 -0
- package/dist/budget/token-tracker.js.map +1 -0
- package/dist/budget/types.d.ts +41 -0
- package/dist/budget/types.d.ts.map +1 -0
- package/dist/budget/types.js +5 -0
- package/dist/budget/types.js.map +1 -0
- package/dist/confidence/__tests__/confidence.test.d.ts +2 -0
- package/dist/confidence/__tests__/confidence.test.d.ts.map +1 -0
- package/dist/confidence/__tests__/confidence.test.js +336 -0
- package/dist/confidence/__tests__/confidence.test.js.map +1 -0
- package/dist/confidence/erosion.d.ts +33 -0
- package/dist/confidence/erosion.d.ts.map +1 -0
- package/dist/confidence/erosion.js +42 -0
- package/dist/confidence/erosion.js.map +1 -0
- package/dist/confidence/index.d.ts +42 -0
- package/dist/confidence/index.d.ts.map +1 -0
- package/dist/confidence/index.js +168 -0
- package/dist/confidence/index.js.map +1 -0
- package/dist/confidence/types.d.ts +29 -0
- package/dist/confidence/types.d.ts.map +1 -0
- package/dist/confidence/types.js +5 -0
- package/dist/confidence/types.js.map +1 -0
- package/dist/curiosity/__tests__/curiosity.test.d.ts +2 -0
- package/dist/curiosity/__tests__/curiosity.test.d.ts.map +1 -0
- package/dist/curiosity/__tests__/curiosity.test.js +280 -0
- package/dist/curiosity/__tests__/curiosity.test.js.map +1 -0
- package/dist/curiosity/dedup.d.ts +29 -0
- package/dist/curiosity/dedup.d.ts.map +1 -0
- package/dist/curiosity/dedup.js +64 -0
- package/dist/curiosity/dedup.js.map +1 -0
- package/dist/curiosity/index.d.ts +56 -0
- package/dist/curiosity/index.d.ts.map +1 -0
- package/dist/curiosity/index.js +163 -0
- package/dist/curiosity/index.js.map +1 -0
- package/dist/curiosity/types.d.ts +29 -0
- package/dist/curiosity/types.d.ts.map +1 -0
- package/dist/curiosity/types.js +5 -0
- package/dist/curiosity/types.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +7 -0
- package/dist/index.test.js.map +1 -0
- package/dist/init.d.ts +17 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +153 -0
- package/dist/init.js.map +1 -0
- package/dist/knowledge-tree/__tests__/knowledge-tree.test.d.ts +2 -0
- package/dist/knowledge-tree/__tests__/knowledge-tree.test.d.ts.map +1 -0
- package/dist/knowledge-tree/__tests__/knowledge-tree.test.js +317 -0
- package/dist/knowledge-tree/__tests__/knowledge-tree.test.js.map +1 -0
- package/dist/knowledge-tree/format.d.ts +17 -0
- package/dist/knowledge-tree/format.d.ts.map +1 -0
- package/dist/knowledge-tree/format.js +48 -0
- package/dist/knowledge-tree/format.js.map +1 -0
- package/dist/knowledge-tree/index.d.ts +33 -0
- package/dist/knowledge-tree/index.d.ts.map +1 -0
- package/dist/knowledge-tree/index.js +182 -0
- package/dist/knowledge-tree/index.js.map +1 -0
- package/dist/knowledge-tree/types.d.ts +37 -0
- package/dist/knowledge-tree/types.d.ts.map +1 -0
- package/dist/knowledge-tree/types.js +5 -0
- package/dist/knowledge-tree/types.js.map +1 -0
- package/dist/metadata/__tests__/metadata.test.d.ts +2 -0
- package/dist/metadata/__tests__/metadata.test.d.ts.map +1 -0
- package/dist/metadata/__tests__/metadata.test.js +196 -0
- package/dist/metadata/__tests__/metadata.test.js.map +1 -0
- package/dist/metadata/__tests__/search.test.d.ts +2 -0
- package/dist/metadata/__tests__/search.test.d.ts.map +1 -0
- package/dist/metadata/__tests__/search.test.js +227 -0
- package/dist/metadata/__tests__/search.test.js.map +1 -0
- package/dist/metadata/index.d.ts +29 -0
- package/dist/metadata/index.d.ts.map +1 -0
- package/dist/metadata/index.js +108 -0
- package/dist/metadata/index.js.map +1 -0
- package/dist/metadata/schema.d.ts +8 -0
- package/dist/metadata/schema.d.ts.map +1 -0
- package/dist/metadata/schema.js +31 -0
- package/dist/metadata/schema.js.map +1 -0
- package/dist/metadata/search.d.ts +27 -0
- package/dist/metadata/search.d.ts.map +1 -0
- package/dist/metadata/search.js +57 -0
- package/dist/metadata/search.js.map +1 -0
- package/dist/metadata/types.d.ts +17 -0
- package/dist/metadata/types.d.ts.map +1 -0
- package/dist/metadata/types.js +5 -0
- package/dist/metadata/types.js.map +1 -0
- package/dist/orchestrator/__tests__/orchestrator.test.d.ts +2 -0
- package/dist/orchestrator/__tests__/orchestrator.test.d.ts.map +1 -0
- package/dist/orchestrator/__tests__/orchestrator.test.js +354 -0
- package/dist/orchestrator/__tests__/orchestrator.test.js.map +1 -0
- package/dist/orchestrator/index.d.ts +23 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +302 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/scheduler.d.ts +32 -0
- package/dist/orchestrator/scheduler.d.ts.map +1 -0
- package/dist/orchestrator/scheduler.js +102 -0
- package/dist/orchestrator/scheduler.js.map +1 -0
- package/dist/orchestrator/types.d.ts +90 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/orchestrator/types.js +5 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/pipeline/__tests__/pipeline.test.d.ts +2 -0
- package/dist/pipeline/__tests__/pipeline.test.d.ts.map +1 -0
- package/dist/pipeline/__tests__/pipeline.test.js +320 -0
- package/dist/pipeline/__tests__/pipeline.test.js.map +1 -0
- package/dist/pipeline/index.d.ts +23 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +212 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/types.d.ts +41 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +5 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/providers/__tests__/providers.test.d.ts +2 -0
- package/dist/providers/__tests__/providers.test.d.ts.map +1 -0
- package/dist/providers/__tests__/providers.test.js +195 -0
- package/dist/providers/__tests__/providers.test.js.map +1 -0
- package/dist/providers/claude-model.d.ts +17 -0
- package/dist/providers/claude-model.d.ts.map +1 -0
- package/dist/providers/claude-model.js +119 -0
- package/dist/providers/claude-model.js.map +1 -0
- package/dist/providers/index.d.ts +22 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +38 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai-search.d.ts +14 -0
- package/dist/providers/openai-search.d.ts.map +1 -0
- package/dist/providers/openai-search.js +97 -0
- package/dist/providers/openai-search.js.map +1 -0
- package/dist/providers/types.d.ts +42 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +5 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/types.d.ts +122 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/vetter/__tests__/vetter.test.d.ts +2 -0
- package/dist/vetter/__tests__/vetter.test.d.ts.map +1 -0
- package/dist/vetter/__tests__/vetter.test.js +224 -0
- package/dist/vetter/__tests__/vetter.test.js.map +1 -0
- package/dist/vetter/index.d.ts +23 -0
- package/dist/vetter/index.d.ts.map +1 -0
- package/dist/vetter/index.js +177 -0
- package/dist/vetter/index.js.map +1 -0
- package/dist/vetter/resource-tracker.d.ts +49 -0
- package/dist/vetter/resource-tracker.d.ts.map +1 -0
- package/dist/vetter/resource-tracker.js +183 -0
- package/dist/vetter/resource-tracker.js.map +1 -0
- package/dist/vetter/types.d.ts +44 -0
- package/dist/vetter/types.d.ts.map +1 -0
- package/dist/vetter/types.js +5 -0
- package/dist/vetter/types.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { initMetadataDb, closeDb } from "../../metadata/index.js";
|
|
6
|
+
import { initCuriosityQueue, addCuriosity, getItem } from "../../curiosity/index.js";
|
|
7
|
+
import { initKnowledgeTree, writeEntry, readEntry } from "../../knowledge-tree/index.js";
|
|
8
|
+
import { runPipeline } from "../index.js";
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Mock providers
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
class MockSearchProvider {
|
|
13
|
+
name = "mock-search";
|
|
14
|
+
_lastCost = 0;
|
|
15
|
+
_results;
|
|
16
|
+
_shouldFail = false;
|
|
17
|
+
constructor(results, shouldFail = false) {
|
|
18
|
+
this._results = results ?? [
|
|
19
|
+
{
|
|
20
|
+
title: "What is quantum computing",
|
|
21
|
+
url: "https://example.com/quantum",
|
|
22
|
+
snippet: "Quantum computing uses qubits to perform calculations.",
|
|
23
|
+
content: "Quantum computing is a type of computation that harnesses quantum mechanics.",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
title: "Quantum basics explained",
|
|
27
|
+
url: "https://example.com/basics",
|
|
28
|
+
snippet: "An introduction to quantum computing concepts and principles.",
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
this._shouldFail = shouldFail;
|
|
32
|
+
}
|
|
33
|
+
async search(_query, maxResults = 5) {
|
|
34
|
+
if (this._shouldFail)
|
|
35
|
+
throw new Error("Search API unavailable");
|
|
36
|
+
this._lastCost = 0.01;
|
|
37
|
+
return this._results.slice(0, maxResults);
|
|
38
|
+
}
|
|
39
|
+
lastCallCostUsd() {
|
|
40
|
+
return this._lastCost;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
class MockModelProvider {
|
|
44
|
+
name = "mock-model";
|
|
45
|
+
_lastCost = 0;
|
|
46
|
+
_shouldFail = false;
|
|
47
|
+
_synthesisOverride;
|
|
48
|
+
constructor(shouldFail = false, synthesisOverride) {
|
|
49
|
+
this._shouldFail = shouldFail;
|
|
50
|
+
this._synthesisOverride = synthesisOverride;
|
|
51
|
+
}
|
|
52
|
+
async synthesize(question, searchResults) {
|
|
53
|
+
if (this._shouldFail)
|
|
54
|
+
throw new Error("Model API unavailable");
|
|
55
|
+
this._lastCost = 0.002;
|
|
56
|
+
return {
|
|
57
|
+
title: `Understanding: ${question}`,
|
|
58
|
+
category: "technology",
|
|
59
|
+
content: `Comprehensive answer synthesised from ${searchResults.length} sources about ${question}.`,
|
|
60
|
+
tags: ["research", "technology"],
|
|
61
|
+
source: searchResults[0]?.url ?? "unknown",
|
|
62
|
+
confidence: 0.85,
|
|
63
|
+
...this._synthesisOverride,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
async categorize(_content, categories) {
|
|
67
|
+
this._lastCost = 0.001;
|
|
68
|
+
return categories[0] ?? "general";
|
|
69
|
+
}
|
|
70
|
+
lastCallCostUsd() {
|
|
71
|
+
return this._lastCost;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Test setup
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
let tmpDir;
|
|
78
|
+
let dataDir;
|
|
79
|
+
beforeEach(async () => {
|
|
80
|
+
tmpDir = await mkdtemp(join(tmpdir(), "cq-pipeline-test-"));
|
|
81
|
+
dataDir = join(tmpDir, "knowledge");
|
|
82
|
+
await initKnowledgeTree(dataDir);
|
|
83
|
+
initMetadataDb(":memory:");
|
|
84
|
+
initCuriosityQueue();
|
|
85
|
+
});
|
|
86
|
+
afterEach(async () => {
|
|
87
|
+
closeDb();
|
|
88
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
89
|
+
});
|
|
90
|
+
function addTestItem(question = "What is quantum computing?") {
|
|
91
|
+
const item = addCuriosity({
|
|
92
|
+
question,
|
|
93
|
+
context: "Test context",
|
|
94
|
+
source: "agent",
|
|
95
|
+
priority: 5,
|
|
96
|
+
});
|
|
97
|
+
if (!item)
|
|
98
|
+
throw new Error("Failed to add curiosity item");
|
|
99
|
+
return item.id;
|
|
100
|
+
}
|
|
101
|
+
function makeOptions(overrides = {}) {
|
|
102
|
+
return {
|
|
103
|
+
dataDir,
|
|
104
|
+
searchProvider: new MockSearchProvider(),
|
|
105
|
+
modelProvider: new MockModelProvider(),
|
|
106
|
+
...overrides,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
// Happy path
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
describe("runPipeline — happy path", () => {
|
|
113
|
+
it("creates a knowledge entry and returns success", async () => {
|
|
114
|
+
const id = addTestItem();
|
|
115
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions());
|
|
116
|
+
expect(result.success).toBe(true);
|
|
117
|
+
expect(result.action).toBe("created");
|
|
118
|
+
expect(result.curiosityItemId).toBe(id);
|
|
119
|
+
expect(result.knowledgeSlug).toBeDefined();
|
|
120
|
+
expect(result.knowledgeCategory).toBe("technology");
|
|
121
|
+
expect(result.durationMs).toBeGreaterThanOrEqual(0);
|
|
122
|
+
expect(result.error).toBeUndefined();
|
|
123
|
+
});
|
|
124
|
+
it("writes the entry to the knowledge tree", async () => {
|
|
125
|
+
const id = addTestItem();
|
|
126
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions());
|
|
127
|
+
const entry = await readEntry(dataDir, result.knowledgeCategory, result.knowledgeSlug);
|
|
128
|
+
expect(entry.title).toContain("quantum computing");
|
|
129
|
+
expect(entry.content.length).toBeGreaterThan(0);
|
|
130
|
+
expect(entry.tags).toContain("research");
|
|
131
|
+
});
|
|
132
|
+
it("marks the curiosity item as completed", async () => {
|
|
133
|
+
const id = addTestItem();
|
|
134
|
+
await runPipeline(id, "What is quantum computing?", makeOptions());
|
|
135
|
+
const item = getItem(id);
|
|
136
|
+
expect(item?.status).toBe("completed");
|
|
137
|
+
});
|
|
138
|
+
it("tracks duration in milliseconds", async () => {
|
|
139
|
+
const id = addTestItem();
|
|
140
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions());
|
|
141
|
+
expect(typeof result.durationMs).toBe("number");
|
|
142
|
+
expect(result.durationMs).toBeGreaterThanOrEqual(0);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
// Budget checking
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
describe("runPipeline — budget checking", () => {
|
|
149
|
+
it("skips execution when budget is not allowed", async () => {
|
|
150
|
+
const id = addTestItem();
|
|
151
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions({
|
|
152
|
+
checkBudget: () => ({ allowed: false, remainingUsd: 0 }),
|
|
153
|
+
}));
|
|
154
|
+
expect(result.success).toBe(false);
|
|
155
|
+
expect(result.action).toBe("skipped_budget");
|
|
156
|
+
expect(result.error).toBeUndefined();
|
|
157
|
+
// Item should NOT be marked in_progress (budget check is before)
|
|
158
|
+
const item = getItem(id);
|
|
159
|
+
expect(item?.status).toBe("pending");
|
|
160
|
+
});
|
|
161
|
+
it("proceeds when budget is allowed", async () => {
|
|
162
|
+
const id = addTestItem();
|
|
163
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions({
|
|
164
|
+
checkBudget: () => ({ allowed: true, remainingUsd: 10.0 }),
|
|
165
|
+
}));
|
|
166
|
+
expect(result.success).toBe(true);
|
|
167
|
+
expect(result.action).toBe("created");
|
|
168
|
+
});
|
|
169
|
+
it("calls charge function for search and synthesis", async () => {
|
|
170
|
+
const charges = [];
|
|
171
|
+
const id = addTestItem();
|
|
172
|
+
await runPipeline(id, "What is quantum computing?", makeOptions({
|
|
173
|
+
charge: (type, costUsd) => charges.push({ type, costUsd }),
|
|
174
|
+
}));
|
|
175
|
+
const searchCharge = charges.find((c) => c.type === "search");
|
|
176
|
+
const synthCharge = charges.find((c) => c.type === "synthesize");
|
|
177
|
+
expect(searchCharge).toBeDefined();
|
|
178
|
+
expect(searchCharge.costUsd).toBe(0.01);
|
|
179
|
+
expect(synthCharge).toBeDefined();
|
|
180
|
+
expect(synthCharge.costUsd).toBe(0.002);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
// Duplicate detection
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
describe("runPipeline — duplicate detection", () => {
|
|
187
|
+
it("skips when a knowledge entry with similar title exists", async () => {
|
|
188
|
+
// Pre-populate knowledge tree with an entry in the same category
|
|
189
|
+
await writeEntry(dataDir, {
|
|
190
|
+
category: "technology",
|
|
191
|
+
title: "Understanding: What is quantum computing?",
|
|
192
|
+
content: "Existing entry about quantum computing.",
|
|
193
|
+
tags: ["quantum"],
|
|
194
|
+
});
|
|
195
|
+
const id = addTestItem();
|
|
196
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions());
|
|
197
|
+
expect(result.success).toBe(true);
|
|
198
|
+
expect(result.action).toBe("skipped_duplicate");
|
|
199
|
+
expect(result.knowledgeCategory).toBe("technology");
|
|
200
|
+
});
|
|
201
|
+
it("creates entry when titles are sufficiently different", async () => {
|
|
202
|
+
// Pre-populate with a very different topic
|
|
203
|
+
await writeEntry(dataDir, {
|
|
204
|
+
category: "technology",
|
|
205
|
+
title: "Understanding blockchain fundamentals",
|
|
206
|
+
content: "Blockchain is a distributed ledger technology.",
|
|
207
|
+
tags: ["blockchain"],
|
|
208
|
+
});
|
|
209
|
+
const id = addTestItem();
|
|
210
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions());
|
|
211
|
+
expect(result.success).toBe(true);
|
|
212
|
+
expect(result.action).toBe("created");
|
|
213
|
+
});
|
|
214
|
+
it("respects custom dedup threshold", async () => {
|
|
215
|
+
await writeEntry(dataDir, {
|
|
216
|
+
category: "technology",
|
|
217
|
+
title: "Understanding quantum computing basics",
|
|
218
|
+
content: "Existing entry.",
|
|
219
|
+
tags: [],
|
|
220
|
+
});
|
|
221
|
+
const id = addTestItem();
|
|
222
|
+
// Very high threshold — should NOT trigger dedup
|
|
223
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions({ dedupThreshold: 0.99 }));
|
|
224
|
+
expect(result.action).toBe("created");
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
// ---------------------------------------------------------------------------
|
|
228
|
+
// Error handling
|
|
229
|
+
// ---------------------------------------------------------------------------
|
|
230
|
+
describe("runPipeline — error handling", () => {
|
|
231
|
+
it("handles search provider failure", async () => {
|
|
232
|
+
const id = addTestItem();
|
|
233
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions({
|
|
234
|
+
searchProvider: new MockSearchProvider(undefined, true),
|
|
235
|
+
}));
|
|
236
|
+
expect(result.success).toBe(false);
|
|
237
|
+
expect(result.action).toBe("failed");
|
|
238
|
+
expect(result.error).toContain("Search failed");
|
|
239
|
+
const item = getItem(id);
|
|
240
|
+
expect(item?.status).toBe("failed");
|
|
241
|
+
});
|
|
242
|
+
it("handles model provider failure", async () => {
|
|
243
|
+
const id = addTestItem();
|
|
244
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions({
|
|
245
|
+
modelProvider: new MockModelProvider(true),
|
|
246
|
+
}));
|
|
247
|
+
expect(result.success).toBe(false);
|
|
248
|
+
expect(result.action).toBe("failed");
|
|
249
|
+
expect(result.error).toContain("Synthesis failed");
|
|
250
|
+
const item = getItem(id);
|
|
251
|
+
expect(item?.status).toBe("failed");
|
|
252
|
+
});
|
|
253
|
+
it("fails when all search results are too short", async () => {
|
|
254
|
+
const shortResults = [
|
|
255
|
+
{ title: "Short", url: "https://example.com", snippet: "tiny" },
|
|
256
|
+
];
|
|
257
|
+
const id = addTestItem();
|
|
258
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions({
|
|
259
|
+
searchProvider: new MockSearchProvider(shortResults),
|
|
260
|
+
}));
|
|
261
|
+
expect(result.success).toBe(false);
|
|
262
|
+
expect(result.action).toBe("failed");
|
|
263
|
+
expect(result.error).toContain("No search results passed vetting");
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
// ---------------------------------------------------------------------------
|
|
267
|
+
// Vetting
|
|
268
|
+
// ---------------------------------------------------------------------------
|
|
269
|
+
describe("runPipeline — vetting", () => {
|
|
270
|
+
it("filters out results below minimum content length", async () => {
|
|
271
|
+
const mixedResults = [
|
|
272
|
+
{ title: "Short", url: "https://example.com/1", snippet: "too short" },
|
|
273
|
+
{
|
|
274
|
+
title: "Long enough",
|
|
275
|
+
url: "https://example.com/2",
|
|
276
|
+
snippet: "This result has enough content to pass the vetting threshold.",
|
|
277
|
+
},
|
|
278
|
+
];
|
|
279
|
+
const id = addTestItem();
|
|
280
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions({
|
|
281
|
+
searchProvider: new MockSearchProvider(mixedResults),
|
|
282
|
+
}));
|
|
283
|
+
// Should succeed because one result passes vetting
|
|
284
|
+
expect(result.success).toBe(true);
|
|
285
|
+
expect(result.action).toBe("created");
|
|
286
|
+
});
|
|
287
|
+
it("respects custom minimum content length", async () => {
|
|
288
|
+
const results = [
|
|
289
|
+
{
|
|
290
|
+
title: "Medium",
|
|
291
|
+
url: "https://example.com",
|
|
292
|
+
snippet: "A medium-length snippet that is 50+ chars long for testing purposes here.",
|
|
293
|
+
},
|
|
294
|
+
];
|
|
295
|
+
const id = addTestItem();
|
|
296
|
+
const result = await runPipeline(id, "What is quantum computing?", makeOptions({
|
|
297
|
+
searchProvider: new MockSearchProvider(results),
|
|
298
|
+
minContentLength: 200, // Very high threshold
|
|
299
|
+
}));
|
|
300
|
+
expect(result.success).toBe(false);
|
|
301
|
+
expect(result.action).toBe("failed");
|
|
302
|
+
expect(result.error).toContain("No search results passed vetting");
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
// ---------------------------------------------------------------------------
|
|
306
|
+
// Pipeline without optional parameters
|
|
307
|
+
// ---------------------------------------------------------------------------
|
|
308
|
+
describe("runPipeline — optional parameters", () => {
|
|
309
|
+
it("works without budget checker or charge function", async () => {
|
|
310
|
+
const id = addTestItem();
|
|
311
|
+
const result = await runPipeline(id, "What is quantum computing?", {
|
|
312
|
+
dataDir,
|
|
313
|
+
searchProvider: new MockSearchProvider(),
|
|
314
|
+
modelProvider: new MockModelProvider(),
|
|
315
|
+
});
|
|
316
|
+
expect(result.success).toBe(true);
|
|
317
|
+
expect(result.action).toBe("created");
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
//# sourceMappingURL=pipeline.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.test.js","sourceRoot":"","sources":["../../../src/pipeline/__tests__/pipeline.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Research Pipeline — the core engine connecting curiosity queue to knowledge tree.
|
|
3
|
+
*
|
|
4
|
+
* Flow: check budget > mark in_progress > search > vet resources > synthesize >
|
|
5
|
+
* categorize > dedup check > write knowledge + index > mark completed
|
|
6
|
+
*/
|
|
7
|
+
import type { PipelineResult, PipelineOptions } from "./types.js";
|
|
8
|
+
export type { PipelineResult, PipelineOptions, PipelineAction, BudgetCheck } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Run the full research pipeline for a single curiosity item.
|
|
11
|
+
*
|
|
12
|
+
* Steps:
|
|
13
|
+
* 1. Check budget (if checker provided)
|
|
14
|
+
* 2. Mark curiosity item as in_progress
|
|
15
|
+
* 3. Search for the question via search provider
|
|
16
|
+
* 4. Vet search results (filter low-quality)
|
|
17
|
+
* 5. Synthesize results via model provider
|
|
18
|
+
* 6. Duplicate detection against existing knowledge
|
|
19
|
+
* 7. Write knowledge entry + index metadata
|
|
20
|
+
* 8. Mark curiosity item as completed
|
|
21
|
+
*/
|
|
22
|
+
export declare function runPipeline(curiosityItemId: number, question: string, options: PipelineOptions): Promise<PipelineResult>;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pipeline/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAiE/F;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAC/B,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAkKzB"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Research Pipeline — the core engine connecting curiosity queue to knowledge tree.
|
|
3
|
+
*
|
|
4
|
+
* Flow: check budget > mark in_progress > search > vet resources > synthesize >
|
|
5
|
+
* categorize > dedup check > write knowledge + index > mark completed
|
|
6
|
+
*/
|
|
7
|
+
import { writeEntry, readEntry } from "../knowledge-tree/index.js";
|
|
8
|
+
import { indexEntry } from "../metadata/index.js";
|
|
9
|
+
import { markInProgress, markCompleted, markFailed, } from "../curiosity/index.js";
|
|
10
|
+
import { normalizedSimilarity } from "../curiosity/dedup.js";
|
|
11
|
+
import { listEntries } from "../knowledge-tree/index.js";
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Constants
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
const DEFAULT_MAX_RESULTS = 5;
|
|
16
|
+
const DEFAULT_MIN_CONTENT_LENGTH = 20;
|
|
17
|
+
const DEFAULT_DEDUP_THRESHOLD = 0.8;
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Vetting (basic inline — US-007 will build the full vetter)
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/** Basic content vetting: checks that search results have meaningful content. */
|
|
22
|
+
function vetResults(results, minContentLength) {
|
|
23
|
+
return results.filter((r) => {
|
|
24
|
+
const text = r.content ?? r.snippet;
|
|
25
|
+
return text.length >= minContentLength;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Dedup
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
/**
|
|
32
|
+
* Check if a title is a duplicate of any existing knowledge entry.
|
|
33
|
+
* Uses normalized Levenshtein similarity from the curiosity dedup module.
|
|
34
|
+
*/
|
|
35
|
+
async function isDuplicateKnowledge(dataDir, title, category, threshold) {
|
|
36
|
+
let entries;
|
|
37
|
+
try {
|
|
38
|
+
entries = await listEntries(dataDir, category);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Category doesn't exist yet — no duplicates possible
|
|
42
|
+
return { duplicate: false };
|
|
43
|
+
}
|
|
44
|
+
const normalizedTitle = title.toLowerCase().trim();
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
const similarity = normalizedSimilarity(normalizedTitle, entry.title.toLowerCase().trim());
|
|
47
|
+
if (similarity > threshold) {
|
|
48
|
+
return { duplicate: true, existingSlug: entry.slug };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { duplicate: false };
|
|
52
|
+
}
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Pipeline
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
/**
|
|
57
|
+
* Run the full research pipeline for a single curiosity item.
|
|
58
|
+
*
|
|
59
|
+
* Steps:
|
|
60
|
+
* 1. Check budget (if checker provided)
|
|
61
|
+
* 2. Mark curiosity item as in_progress
|
|
62
|
+
* 3. Search for the question via search provider
|
|
63
|
+
* 4. Vet search results (filter low-quality)
|
|
64
|
+
* 5. Synthesize results via model provider
|
|
65
|
+
* 6. Duplicate detection against existing knowledge
|
|
66
|
+
* 7. Write knowledge entry + index metadata
|
|
67
|
+
* 8. Mark curiosity item as completed
|
|
68
|
+
*/
|
|
69
|
+
export async function runPipeline(curiosityItemId, question, options) {
|
|
70
|
+
const startTime = Date.now();
|
|
71
|
+
const { dataDir, searchProvider, modelProvider, checkBudget, charge, maxSearchResults = DEFAULT_MAX_RESULTS, minContentLength = DEFAULT_MIN_CONTENT_LENGTH, dedupThreshold = DEFAULT_DEDUP_THRESHOLD, } = options;
|
|
72
|
+
// --- Step 1: Budget check ---
|
|
73
|
+
if (checkBudget) {
|
|
74
|
+
const budget = checkBudget();
|
|
75
|
+
if (!budget.allowed) {
|
|
76
|
+
return {
|
|
77
|
+
curiosityItemId,
|
|
78
|
+
success: false,
|
|
79
|
+
action: "skipped_budget",
|
|
80
|
+
durationMs: Date.now() - startTime,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// --- Step 2: Mark in_progress ---
|
|
85
|
+
try {
|
|
86
|
+
markInProgress(curiosityItemId);
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
return {
|
|
90
|
+
curiosityItemId,
|
|
91
|
+
success: false,
|
|
92
|
+
action: "failed",
|
|
93
|
+
error: `Failed to mark in_progress: ${err instanceof Error ? err.message : String(err)}`,
|
|
94
|
+
durationMs: Date.now() - startTime,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// --- Step 3: Search ---
|
|
98
|
+
let searchResults;
|
|
99
|
+
try {
|
|
100
|
+
searchResults = await searchProvider.search(question, maxSearchResults);
|
|
101
|
+
if (charge) {
|
|
102
|
+
charge("search", searchProvider.lastCallCostUsd());
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
const errorMsg = `Search failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
107
|
+
markFailed(curiosityItemId, errorMsg);
|
|
108
|
+
return {
|
|
109
|
+
curiosityItemId,
|
|
110
|
+
success: false,
|
|
111
|
+
action: "failed",
|
|
112
|
+
error: errorMsg,
|
|
113
|
+
durationMs: Date.now() - startTime,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// --- Step 4: Vet resources ---
|
|
117
|
+
const vettedResults = vetResults(searchResults, minContentLength);
|
|
118
|
+
if (vettedResults.length === 0) {
|
|
119
|
+
const errorMsg = "No search results passed vetting";
|
|
120
|
+
markFailed(curiosityItemId, errorMsg);
|
|
121
|
+
return {
|
|
122
|
+
curiosityItemId,
|
|
123
|
+
success: false,
|
|
124
|
+
action: "failed",
|
|
125
|
+
error: errorMsg,
|
|
126
|
+
durationMs: Date.now() - startTime,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
// --- Step 5: Synthesize ---
|
|
130
|
+
let synthesis;
|
|
131
|
+
try {
|
|
132
|
+
synthesis = await modelProvider.synthesize(question, vettedResults);
|
|
133
|
+
if (charge) {
|
|
134
|
+
charge("synthesize", modelProvider.lastCallCostUsd());
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
const errorMsg = `Synthesis failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
139
|
+
markFailed(curiosityItemId, errorMsg);
|
|
140
|
+
return {
|
|
141
|
+
curiosityItemId,
|
|
142
|
+
success: false,
|
|
143
|
+
action: "failed",
|
|
144
|
+
error: errorMsg,
|
|
145
|
+
durationMs: Date.now() - startTime,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// --- Step 6: Categorize (use model's suggested category) ---
|
|
149
|
+
const category = synthesis.category;
|
|
150
|
+
// --- Step 7: Dedup check ---
|
|
151
|
+
try {
|
|
152
|
+
const dedup = await isDuplicateKnowledge(dataDir, synthesis.title, category, dedupThreshold);
|
|
153
|
+
if (dedup.duplicate) {
|
|
154
|
+
markCompleted(curiosityItemId);
|
|
155
|
+
return {
|
|
156
|
+
curiosityItemId,
|
|
157
|
+
success: true,
|
|
158
|
+
action: "skipped_duplicate",
|
|
159
|
+
knowledgeSlug: dedup.existingSlug,
|
|
160
|
+
knowledgeCategory: category,
|
|
161
|
+
durationMs: Date.now() - startTime,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// Dedup failure is non-fatal — proceed with creation
|
|
167
|
+
}
|
|
168
|
+
// --- Step 8: Write knowledge entry + index ---
|
|
169
|
+
let entrySlug;
|
|
170
|
+
try {
|
|
171
|
+
entrySlug = await writeEntry(dataDir, {
|
|
172
|
+
category,
|
|
173
|
+
title: synthesis.title,
|
|
174
|
+
content: synthesis.content,
|
|
175
|
+
tags: synthesis.tags,
|
|
176
|
+
source: synthesis.source,
|
|
177
|
+
});
|
|
178
|
+
// Index in metadata store
|
|
179
|
+
const entry = await readEntry(dataDir, category, entrySlug);
|
|
180
|
+
indexEntry(entry);
|
|
181
|
+
if (charge) {
|
|
182
|
+
charge("write", 0); // Writing is free
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
const errorMsg = `Failed to write knowledge: ${err instanceof Error ? err.message : String(err)}`;
|
|
187
|
+
markFailed(curiosityItemId, errorMsg);
|
|
188
|
+
return {
|
|
189
|
+
curiosityItemId,
|
|
190
|
+
success: false,
|
|
191
|
+
action: "failed",
|
|
192
|
+
error: errorMsg,
|
|
193
|
+
durationMs: Date.now() - startTime,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
// --- Step 9: Mark completed ---
|
|
197
|
+
try {
|
|
198
|
+
markCompleted(curiosityItemId);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Non-fatal — knowledge was written successfully
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
curiosityItemId,
|
|
205
|
+
success: true,
|
|
206
|
+
action: "created",
|
|
207
|
+
knowledgeSlug: entrySlug,
|
|
208
|
+
knowledgeCategory: category,
|
|
209
|
+
durationMs: Date.now() - startTime,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pipeline/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline type definitions — research pipeline connecting curiosity to knowledge.
|
|
3
|
+
*/
|
|
4
|
+
import type { SearchProvider, ModelProvider } from "../providers/types.js";
|
|
5
|
+
/** Possible outcomes of a pipeline run. */
|
|
6
|
+
export type PipelineAction = "created" | "updated" | "skipped_duplicate" | "skipped_budget" | "failed";
|
|
7
|
+
/** Result returned by runPipeline. */
|
|
8
|
+
export interface PipelineResult {
|
|
9
|
+
curiosityItemId: number;
|
|
10
|
+
success: boolean;
|
|
11
|
+
action: PipelineAction;
|
|
12
|
+
knowledgeSlug?: string;
|
|
13
|
+
knowledgeCategory?: string;
|
|
14
|
+
error?: string;
|
|
15
|
+
durationMs: number;
|
|
16
|
+
}
|
|
17
|
+
/** Budget checker — returns whether execution is allowed and remaining funds. */
|
|
18
|
+
export interface BudgetCheck {
|
|
19
|
+
allowed: boolean;
|
|
20
|
+
remainingUsd: number;
|
|
21
|
+
}
|
|
22
|
+
/** Options bag for runPipeline. */
|
|
23
|
+
export interface PipelineOptions {
|
|
24
|
+
/** Root directory for the knowledge tree. */
|
|
25
|
+
dataDir: string;
|
|
26
|
+
/** Search provider instance. */
|
|
27
|
+
searchProvider: SearchProvider;
|
|
28
|
+
/** Model provider instance. */
|
|
29
|
+
modelProvider: ModelProvider;
|
|
30
|
+
/** Optional budget check — called before execution starts. */
|
|
31
|
+
checkBudget?: () => BudgetCheck;
|
|
32
|
+
/** Optional charge function — called after each billable step. */
|
|
33
|
+
charge?: (type: string, costUsd: number) => void;
|
|
34
|
+
/** Maximum search results to fetch (default: 5). */
|
|
35
|
+
maxSearchResults?: number;
|
|
36
|
+
/** Minimum content length (chars) to consider a search result meaningful (default: 20). */
|
|
37
|
+
minContentLength?: number;
|
|
38
|
+
/** Levenshtein similarity threshold for duplicate detection (default: 0.8). */
|
|
39
|
+
dedupThreshold?: number;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAM3E,2CAA2C;AAC3C,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,SAAS,GACT,mBAAmB,GACnB,gBAAgB,GAChB,QAAQ,CAAC;AAEb,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,iFAAiF;AACjF,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAEhB,gCAAgC;IAChC,cAAc,EAAE,cAAc,CAAC;IAE/B,+BAA+B;IAC/B,aAAa,EAAE,aAAa,CAAC;IAE7B,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,WAAW,CAAC;IAEhC,kEAAkE;IAClE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAEjD,oDAAoD;IACpD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,2FAA2F;IAC3F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.test.d.ts","sourceRoot":"","sources":["../../../src/providers/__tests__/providers.test.ts"],"names":[],"mappings":""}
|