@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
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CQ Public API — top-level configuration and instance types.
|
|
3
|
+
*/
|
|
4
|
+
import type { ConfidenceConfig } from "./confidence/index.js";
|
|
5
|
+
import type { BudgetConfig } from "./budget/index.js";
|
|
6
|
+
import type { TokenTracker } from "./budget/token-tracker.js";
|
|
7
|
+
import type { SearchProvider, ModelProvider } from "./providers/types.js";
|
|
8
|
+
import type { OrchestratorResult } from "./orchestrator/types.js";
|
|
9
|
+
import type Database from "better-sqlite3";
|
|
10
|
+
/** Configuration for initialising the CQ system. */
|
|
11
|
+
export interface CQConfig {
|
|
12
|
+
/** Root directory for the knowledge tree (markdown files). */
|
|
13
|
+
dataDir: string;
|
|
14
|
+
/** Optional budget configuration overrides. */
|
|
15
|
+
budget?: Partial<BudgetConfig>;
|
|
16
|
+
/** Optional confidence configuration overrides. */
|
|
17
|
+
confidence?: Partial<ConfidenceConfig>;
|
|
18
|
+
/** Optional provider overrides. Defaults to OpenAI search + Claude model. */
|
|
19
|
+
providers?: {
|
|
20
|
+
search?: SearchProvider;
|
|
21
|
+
model?: ModelProvider;
|
|
22
|
+
};
|
|
23
|
+
/** Optional scheduler configuration. If provided, the scheduler starts automatically. */
|
|
24
|
+
scheduler?: {
|
|
25
|
+
/** Cron expression: "minute hour dayOfMonth". Default "0 3 *". */
|
|
26
|
+
cron?: string;
|
|
27
|
+
/** Called when a scheduled run completes. */
|
|
28
|
+
onComplete?: (result: OrchestratorResult) => void;
|
|
29
|
+
/** Called when a scheduled run fails. */
|
|
30
|
+
onError?: (error: Error) => void;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** A fully initialised CQ system instance. */
|
|
34
|
+
export interface CQInstance {
|
|
35
|
+
/** Knowledge tree operations (write, read, list, remove entries). */
|
|
36
|
+
knowledge: {
|
|
37
|
+
initKnowledgeTree: (dataDir: string) => Promise<void>;
|
|
38
|
+
writeEntry: typeof import("./knowledge-tree/index.js").writeEntry;
|
|
39
|
+
readEntry: typeof import("./knowledge-tree/index.js").readEntry;
|
|
40
|
+
listEntries: typeof import("./knowledge-tree/index.js").listEntries;
|
|
41
|
+
listCategories: typeof import("./knowledge-tree/index.js").listCategories;
|
|
42
|
+
removeEntry: typeof import("./knowledge-tree/index.js").removeEntry;
|
|
43
|
+
createCategory: typeof import("./knowledge-tree/index.js").createCategory;
|
|
44
|
+
generateIndex: typeof import("./knowledge-tree/index.js").generateIndex;
|
|
45
|
+
generateIndexRecursive: typeof import("./knowledge-tree/index.js").generateIndexRecursive;
|
|
46
|
+
};
|
|
47
|
+
/** Metadata store operations (index, search, query metadata). */
|
|
48
|
+
metadata: {
|
|
49
|
+
indexEntry: typeof import("./metadata/index.js").indexEntry;
|
|
50
|
+
removeFromIndex: typeof import("./metadata/index.js").removeFromIndex;
|
|
51
|
+
getMetadata: typeof import("./metadata/index.js").getMetadata;
|
|
52
|
+
getStaleEntries: typeof import("./metadata/index.js").getStaleEntries;
|
|
53
|
+
search: typeof import("./metadata/search.js").search;
|
|
54
|
+
rebuildIndex: typeof import("./metadata/search.js").rebuildIndex;
|
|
55
|
+
};
|
|
56
|
+
/** Confidence system operations. */
|
|
57
|
+
confidence: {
|
|
58
|
+
setConfidenceConfig: typeof import("./confidence/index.js").setConfidenceConfig;
|
|
59
|
+
getConfidenceConfig: typeof import("./confidence/index.js").getConfidenceConfig;
|
|
60
|
+
getConfidence: typeof import("./confidence/index.js").getConfidence;
|
|
61
|
+
recordVerification: typeof import("./confidence/index.js").recordVerification;
|
|
62
|
+
recordContradiction: typeof import("./confidence/index.js").recordContradiction;
|
|
63
|
+
getRefreshCandidates: typeof import("./confidence/index.js").getRefreshCandidates;
|
|
64
|
+
};
|
|
65
|
+
/** Curiosity queue operations. */
|
|
66
|
+
curiosity: {
|
|
67
|
+
addCuriosity: typeof import("./curiosity/index.js").addCuriosity;
|
|
68
|
+
fetchPending: typeof import("./curiosity/index.js").fetchPending;
|
|
69
|
+
getItem: typeof import("./curiosity/index.js").getItem;
|
|
70
|
+
markInProgress: typeof import("./curiosity/index.js").markInProgress;
|
|
71
|
+
markCompleted: typeof import("./curiosity/index.js").markCompleted;
|
|
72
|
+
markFailed: typeof import("./curiosity/index.js").markFailed;
|
|
73
|
+
dismiss: typeof import("./curiosity/index.js").dismiss;
|
|
74
|
+
countByStatus: typeof import("./curiosity/index.js").countByStatus;
|
|
75
|
+
};
|
|
76
|
+
/** Research pipeline. */
|
|
77
|
+
pipeline: {
|
|
78
|
+
runPipeline: typeof import("./pipeline/index.js").runPipeline;
|
|
79
|
+
};
|
|
80
|
+
/** Resource vetter. */
|
|
81
|
+
vetter: {
|
|
82
|
+
vetResource: typeof import("./vetter/index.js").vetResource;
|
|
83
|
+
trackResourceUsage: typeof import("./vetter/index.js").trackResourceUsage;
|
|
84
|
+
isOverRelied: typeof import("./vetter/index.js").isOverRelied;
|
|
85
|
+
getDomainUsage: typeof import("./vetter/index.js").getDomainUsage;
|
|
86
|
+
getUnderexploredDomains: typeof import("./vetter/index.js").getUnderexploredDomains;
|
|
87
|
+
getResourceUsage: typeof import("./vetter/index.js").getResourceUsage;
|
|
88
|
+
};
|
|
89
|
+
/** Budget tracking. */
|
|
90
|
+
budget: {
|
|
91
|
+
setBudgetConfig: typeof import("./budget/index.js").setBudgetConfig;
|
|
92
|
+
getBudgetConfig: typeof import("./budget/index.js").getBudgetConfig;
|
|
93
|
+
charge: typeof import("./budget/index.js").charge;
|
|
94
|
+
checkBudget: typeof import("./budget/index.js").checkBudget;
|
|
95
|
+
getDailyBudgetStatus: typeof import("./budget/index.js").getDailyBudgetStatus;
|
|
96
|
+
getTotalBudgetStatus: typeof import("./budget/index.js").getTotalBudgetStatus;
|
|
97
|
+
};
|
|
98
|
+
/** Token tracker for context window management. */
|
|
99
|
+
tokenTracker: TokenTracker;
|
|
100
|
+
/** Research orchestrator. */
|
|
101
|
+
orchestrator: {
|
|
102
|
+
runOrchestrator: typeof import("./orchestrator/index.js").runOrchestrator;
|
|
103
|
+
getRecentRuns: typeof import("./orchestrator/index.js").getRecentRuns;
|
|
104
|
+
};
|
|
105
|
+
/** Scheduler control. */
|
|
106
|
+
scheduler: {
|
|
107
|
+
startScheduler: typeof import("./orchestrator/scheduler.js").startScheduler;
|
|
108
|
+
stopScheduler: typeof import("./orchestrator/scheduler.js").stopScheduler;
|
|
109
|
+
isSchedulerRunning: typeof import("./orchestrator/scheduler.js").isSchedulerRunning;
|
|
110
|
+
};
|
|
111
|
+
/** The underlying better-sqlite3 database instance. */
|
|
112
|
+
db: Database.Database;
|
|
113
|
+
/** The data directory path. */
|
|
114
|
+
dataDir: string;
|
|
115
|
+
/** The search provider in use. */
|
|
116
|
+
searchProvider: SearchProvider;
|
|
117
|
+
/** The model provider in use. */
|
|
118
|
+
modelProvider: ModelProvider;
|
|
119
|
+
/** Cleanly shut down all SQLite connections and stop the scheduler. */
|
|
120
|
+
close: () => void;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vetter.test.d.ts","sourceRoot":"","sources":["../../../src/vetter/__tests__/vetter.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { vetResource } from "../index.js";
|
|
3
|
+
import { initResourceTracker, trackResourceUsage, isOverRelied, getDomainUsage, getUnderexploredDomains, getResourceUsage, } from "../resource-tracker.js";
|
|
4
|
+
import { closeResourceTracker } from "../resource-tracker.js";
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Helpers
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
function makeResource(overrides = {}) {
|
|
9
|
+
return {
|
|
10
|
+
title: "Understanding Modern Web Architecture",
|
|
11
|
+
url: "https://developer.mozilla.org/en-US/docs/Web/Architecture",
|
|
12
|
+
snippet: "Modern web architecture has evolved significantly, specifically because of advancements in distributed systems and cloud computing platforms.",
|
|
13
|
+
content: "# Modern Web Architecture\n\nModern web architecture has evolved significantly.\n\n## Key Concepts\n\n- Microservices\n- Serverless\n- Edge computing\n\n```javascript\nconst app = express();\n```\n\nThis guide covers the fundamentals of building scalable web applications.\n\n" +
|
|
14
|
+
"Additional content ".repeat(100),
|
|
15
|
+
...overrides,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function makeMinimalResource(overrides = {}) {
|
|
19
|
+
return {
|
|
20
|
+
title: "Hi",
|
|
21
|
+
url: "http://example.com",
|
|
22
|
+
snippet: "Short",
|
|
23
|
+
...overrides,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
// ===========================================================================
|
|
27
|
+
// Quality Vetting
|
|
28
|
+
// ===========================================================================
|
|
29
|
+
describe("vetResource", () => {
|
|
30
|
+
it("scores a high-quality resource above accept threshold", async () => {
|
|
31
|
+
const result = await vetResource(makeResource());
|
|
32
|
+
expect(result.qualityScore).toBeGreaterThanOrEqual(0.75);
|
|
33
|
+
expect(result.recommendation).toBe("accept");
|
|
34
|
+
expect(result.url).toBe("https://developer.mozilla.org/en-US/docs/Web/Architecture");
|
|
35
|
+
expect(result.signals.length).toBeGreaterThan(0);
|
|
36
|
+
});
|
|
37
|
+
it("scores a minimal resource below quality threshold", async () => {
|
|
38
|
+
const result = await vetResource(makeMinimalResource());
|
|
39
|
+
expect(result.qualityScore).toBeLessThan(0.5);
|
|
40
|
+
expect(result.recommendation).toBe("reject");
|
|
41
|
+
expect(result.reason).toContain("below threshold");
|
|
42
|
+
});
|
|
43
|
+
it("returns 'review' for borderline resources", async () => {
|
|
44
|
+
const resource = makeResource({
|
|
45
|
+
content: "Some content with moderate length to pass basic checks.",
|
|
46
|
+
snippet: "A decent snippet that provides some context about the topic.",
|
|
47
|
+
url: "https://example.com/article",
|
|
48
|
+
title: "Decent Article Title About Things",
|
|
49
|
+
});
|
|
50
|
+
const result = await vetResource(resource, undefined, {
|
|
51
|
+
qualityThreshold: 0.4,
|
|
52
|
+
acceptThreshold: 0.8,
|
|
53
|
+
});
|
|
54
|
+
// With this config the score should land between 0.4 and 0.8
|
|
55
|
+
if (result.qualityScore >= 0.4 && result.qualityScore < 0.8) {
|
|
56
|
+
expect(result.recommendation).toBe("review");
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
it("respects custom quality thresholds", async () => {
|
|
60
|
+
const config = { qualityThreshold: 0.9, acceptThreshold: 0.95 };
|
|
61
|
+
const result = await vetResource(makeResource(), undefined, config);
|
|
62
|
+
// Even a good resource should be "review" or "reject" with very high thresholds
|
|
63
|
+
expect(["review", "reject"]).toContain(result.recommendation);
|
|
64
|
+
});
|
|
65
|
+
it("returns signals array with expected fields", async () => {
|
|
66
|
+
const result = await vetResource(makeResource());
|
|
67
|
+
for (const signal of result.signals) {
|
|
68
|
+
expect(signal).toHaveProperty("signal");
|
|
69
|
+
expect(signal).toHaveProperty("score");
|
|
70
|
+
expect(signal).toHaveProperty("weight");
|
|
71
|
+
expect(signal.score).toBeGreaterThanOrEqual(0);
|
|
72
|
+
expect(signal.score).toBeLessThanOrEqual(1);
|
|
73
|
+
expect(signal.weight).toBeGreaterThan(0);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
it("detects content length signal", async () => {
|
|
77
|
+
const result = await vetResource(makeResource());
|
|
78
|
+
const lengthSignal = result.signals.find((s) => s.signal === "content_length");
|
|
79
|
+
expect(lengthSignal).toBeDefined();
|
|
80
|
+
expect(lengthSignal.score).toBeGreaterThanOrEqual(0.7);
|
|
81
|
+
});
|
|
82
|
+
it("detects structure signal", async () => {
|
|
83
|
+
const result = await vetResource(makeResource());
|
|
84
|
+
const structSignal = result.signals.find((s) => s.signal === "structure");
|
|
85
|
+
expect(structSignal).toBeDefined();
|
|
86
|
+
expect(structSignal.score).toBeGreaterThan(0);
|
|
87
|
+
});
|
|
88
|
+
it("penalises low-quality URL patterns", async () => {
|
|
89
|
+
const resource = makeResource({
|
|
90
|
+
url: "https://www.pinterest.com/pin/12345",
|
|
91
|
+
});
|
|
92
|
+
const result = await vetResource(resource);
|
|
93
|
+
const urlSignal = result.signals.find((s) => s.signal === "url_quality");
|
|
94
|
+
expect(urlSignal).toBeDefined();
|
|
95
|
+
expect(urlSignal.score).toBeLessThan(0.5);
|
|
96
|
+
});
|
|
97
|
+
it("boosts trusted domain scores", async () => {
|
|
98
|
+
const resource = makeResource({
|
|
99
|
+
url: "https://github.com/some/repo",
|
|
100
|
+
});
|
|
101
|
+
const result = await vetResource(resource);
|
|
102
|
+
const urlSignal = result.signals.find((s) => s.signal === "url_quality");
|
|
103
|
+
expect(urlSignal).toBeDefined();
|
|
104
|
+
expect(urlSignal.score).toBeGreaterThanOrEqual(0.9);
|
|
105
|
+
});
|
|
106
|
+
it("rounds quality score to 3 decimal places", async () => {
|
|
107
|
+
const result = await vetResource(makeResource());
|
|
108
|
+
const decimalPlaces = result.qualityScore.toString().split(".")[1]?.length ?? 0;
|
|
109
|
+
expect(decimalPlaces).toBeLessThanOrEqual(3);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
// ===========================================================================
|
|
113
|
+
// Resource Usage Tracking
|
|
114
|
+
// ===========================================================================
|
|
115
|
+
describe("resource-tracker", () => {
|
|
116
|
+
beforeEach(() => {
|
|
117
|
+
initResourceTracker(":memory:");
|
|
118
|
+
});
|
|
119
|
+
afterEach(() => {
|
|
120
|
+
closeResourceTracker();
|
|
121
|
+
});
|
|
122
|
+
describe("trackResourceUsage", () => {
|
|
123
|
+
it("creates a new usage record", () => {
|
|
124
|
+
trackResourceUsage("https://example.com/article", 0.8);
|
|
125
|
+
const usage = getResourceUsage("https://example.com/article");
|
|
126
|
+
expect(usage).toBeDefined();
|
|
127
|
+
expect(usage.url).toBe("https://example.com/article");
|
|
128
|
+
expect(usage.domain).toBe("example.com");
|
|
129
|
+
expect(usage.use_count).toBe(1);
|
|
130
|
+
expect(usage.quality_scores).toEqual([0.8]);
|
|
131
|
+
});
|
|
132
|
+
it("increments use_count on repeat usage", () => {
|
|
133
|
+
trackResourceUsage("https://example.com/article", 0.8);
|
|
134
|
+
trackResourceUsage("https://example.com/article", 0.9);
|
|
135
|
+
trackResourceUsage("https://example.com/article", 0.7);
|
|
136
|
+
const usage = getResourceUsage("https://example.com/article");
|
|
137
|
+
expect(usage.use_count).toBe(3);
|
|
138
|
+
expect(usage.quality_scores).toEqual([0.8, 0.9, 0.7]);
|
|
139
|
+
});
|
|
140
|
+
it("strips www. from domain", () => {
|
|
141
|
+
trackResourceUsage("https://www.example.com/page", 0.5);
|
|
142
|
+
const usage = getResourceUsage("https://www.example.com/page");
|
|
143
|
+
expect(usage.domain).toBe("example.com");
|
|
144
|
+
});
|
|
145
|
+
it("sets timestamps on creation", () => {
|
|
146
|
+
trackResourceUsage("https://example.com/a", 0.5);
|
|
147
|
+
const usage = getResourceUsage("https://example.com/a");
|
|
148
|
+
expect(usage.first_used_at).toBeTruthy();
|
|
149
|
+
expect(usage.last_used_at).toBeTruthy();
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
describe("isOverRelied", () => {
|
|
153
|
+
it("returns false for unknown URLs", () => {
|
|
154
|
+
expect(isOverRelied("https://unknown.com")).toBe(false);
|
|
155
|
+
});
|
|
156
|
+
it("returns false when use_count is at or below threshold", () => {
|
|
157
|
+
for (let i = 0; i < 5; i++) {
|
|
158
|
+
trackResourceUsage("https://example.com/doc", 0.8);
|
|
159
|
+
}
|
|
160
|
+
expect(isOverRelied("https://example.com/doc", 5)).toBe(false);
|
|
161
|
+
});
|
|
162
|
+
it("returns true when use_count exceeds threshold", () => {
|
|
163
|
+
for (let i = 0; i < 6; i++) {
|
|
164
|
+
trackResourceUsage("https://example.com/doc", 0.8);
|
|
165
|
+
}
|
|
166
|
+
expect(isOverRelied("https://example.com/doc", 5)).toBe(true);
|
|
167
|
+
});
|
|
168
|
+
it("uses default maxUses of 5", () => {
|
|
169
|
+
for (let i = 0; i < 6; i++) {
|
|
170
|
+
trackResourceUsage("https://example.com/doc", 0.8);
|
|
171
|
+
}
|
|
172
|
+
expect(isOverRelied("https://example.com/doc")).toBe(true);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
describe("getDomainUsage", () => {
|
|
176
|
+
it("returns undefined for unknown domain", () => {
|
|
177
|
+
expect(getDomainUsage("unknown.com")).toBeUndefined();
|
|
178
|
+
});
|
|
179
|
+
it("aggregates stats across URLs for same domain", () => {
|
|
180
|
+
trackResourceUsage("https://example.com/a", 0.8);
|
|
181
|
+
trackResourceUsage("https://example.com/b", 0.6);
|
|
182
|
+
trackResourceUsage("https://example.com/a", 0.9);
|
|
183
|
+
const stats = getDomainUsage("example.com");
|
|
184
|
+
expect(stats).toBeDefined();
|
|
185
|
+
expect(stats.domain).toBe("example.com");
|
|
186
|
+
expect(stats.total_uses).toBe(3);
|
|
187
|
+
expect(stats.unique_urls).toBe(2);
|
|
188
|
+
expect(stats.avg_quality).toBeCloseTo(0.767, 2);
|
|
189
|
+
});
|
|
190
|
+
it("computes correct avg_quality", () => {
|
|
191
|
+
trackResourceUsage("https://test.org/x", 1.0);
|
|
192
|
+
trackResourceUsage("https://test.org/y", 0.5);
|
|
193
|
+
const stats = getDomainUsage("test.org");
|
|
194
|
+
expect(stats.avg_quality).toBeCloseTo(0.75, 2);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
describe("getUnderexploredDomains", () => {
|
|
198
|
+
it("returns unused domains first", () => {
|
|
199
|
+
trackResourceUsage("https://used.com/page", 0.8);
|
|
200
|
+
const result = getUnderexploredDomains(["used.com", "unused1.com", "unused2.com"], 3);
|
|
201
|
+
expect(result[0]).not.toBe("used.com");
|
|
202
|
+
expect(result).toContain("unused1.com");
|
|
203
|
+
expect(result).toContain("unused2.com");
|
|
204
|
+
});
|
|
205
|
+
it("sorts by usage count ascending", () => {
|
|
206
|
+
trackResourceUsage("https://heavy.com/a", 0.8);
|
|
207
|
+
trackResourceUsage("https://heavy.com/a", 0.8);
|
|
208
|
+
trackResourceUsage("https://heavy.com/a", 0.8);
|
|
209
|
+
trackResourceUsage("https://light.com/b", 0.8);
|
|
210
|
+
const result = getUnderexploredDomains(["heavy.com", "light.com", "zero.com"], 3);
|
|
211
|
+
expect(result[0]).toBe("zero.com");
|
|
212
|
+
expect(result[1]).toBe("light.com");
|
|
213
|
+
expect(result[2]).toBe("heavy.com");
|
|
214
|
+
});
|
|
215
|
+
it("respects limit parameter", () => {
|
|
216
|
+
const result = getUnderexploredDomains(["a.com", "b.com", "c.com", "d.com"], 2);
|
|
217
|
+
expect(result).toHaveLength(2);
|
|
218
|
+
});
|
|
219
|
+
it("returns empty array for empty input", () => {
|
|
220
|
+
expect(getUnderexploredDomains([])).toEqual([]);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
//# sourceMappingURL=vetter.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vetter.test.js","sourceRoot":"","sources":["../../../src/vetter/__tests__/vetter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource Vetter — heuristic quality scoring for web search results.
|
|
3
|
+
*
|
|
4
|
+
* Scores resources on a 0–1 scale using content-based signals (length,
|
|
5
|
+
* structure, snippet quality, URL quality). The optional modelProvider
|
|
6
|
+
* parameter is reserved for future LLM-enhanced vetting.
|
|
7
|
+
*/
|
|
8
|
+
import type { WebSearchResult } from "../providers/types.js";
|
|
9
|
+
import type { ModelProvider } from "../providers/types.js";
|
|
10
|
+
import type { VetResult, VetConfig } from "./types.js";
|
|
11
|
+
export type { VetResult, VetConfig, QualitySignal, VetRecommendation } from "./types.js";
|
|
12
|
+
export type { ResourceUsage, DomainStats } from "./types.js";
|
|
13
|
+
export { initResourceTracker, trackResourceUsage, isOverRelied, getDomainUsage, getUnderexploredDomains, getResourceUsage, } from "./resource-tracker.js";
|
|
14
|
+
/**
|
|
15
|
+
* Vet a resource for quality using content-based heuristics.
|
|
16
|
+
*
|
|
17
|
+
* @param resource - A web search result to evaluate.
|
|
18
|
+
* @param _modelProvider - Reserved for future LLM-enhanced vetting (unused).
|
|
19
|
+
* @param config - Optional thresholds for accept/reject.
|
|
20
|
+
* @returns A VetResult with the quality score, signals, and recommendation.
|
|
21
|
+
*/
|
|
22
|
+
export declare function vetResource(resource: WebSearchResult, _modelProvider?: ModelProvider, config?: VetConfig): Promise<VetResult>;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vetter/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAoC,MAAM,YAAY,CAAC;AAEzF,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzF,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAsI/B;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,eAAe,EACzB,cAAc,CAAC,EAAE,aAAa,EAC9B,MAAM,CAAC,EAAE,SAAS,GACjB,OAAO,CAAC,SAAS,CAAC,CAwCpB"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource Vetter — heuristic quality scoring for web search results.
|
|
3
|
+
*
|
|
4
|
+
* Scores resources on a 0–1 scale using content-based signals (length,
|
|
5
|
+
* structure, snippet quality, URL quality). The optional modelProvider
|
|
6
|
+
* parameter is reserved for future LLM-enhanced vetting.
|
|
7
|
+
*/
|
|
8
|
+
export { initResourceTracker, trackResourceUsage, isOverRelied, getDomainUsage, getUnderexploredDomains, getResourceUsage, } from "./resource-tracker.js";
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Defaults
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
const DEFAULT_QUALITY_THRESHOLD = 0.5;
|
|
13
|
+
const DEFAULT_ACCEPT_THRESHOLD = 0.75;
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Signal detectors
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/** Domains known to be high-quality reference sources. */
|
|
18
|
+
const TRUSTED_DOMAINS = new Set([
|
|
19
|
+
"github.com",
|
|
20
|
+
"stackoverflow.com",
|
|
21
|
+
"developer.mozilla.org",
|
|
22
|
+
"docs.python.org",
|
|
23
|
+
"en.wikipedia.org",
|
|
24
|
+
"arxiv.org",
|
|
25
|
+
"nature.com",
|
|
26
|
+
"science.org",
|
|
27
|
+
"nytimes.com",
|
|
28
|
+
"reuters.com",
|
|
29
|
+
]);
|
|
30
|
+
/** URL patterns that suggest low-quality or aggregator content. */
|
|
31
|
+
const LOW_QUALITY_PATTERNS = [
|
|
32
|
+
/slideshare\.net/,
|
|
33
|
+
/pinterest\.com/,
|
|
34
|
+
/quora\.com/,
|
|
35
|
+
/listicle/i,
|
|
36
|
+
/top-\d+/i,
|
|
37
|
+
];
|
|
38
|
+
function extractDomain(url) {
|
|
39
|
+
try {
|
|
40
|
+
return new URL(url).hostname.replace(/^www\./, "");
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return "";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Score based on content length (longer = more substance). */
|
|
47
|
+
function scoreContentLength(resource) {
|
|
48
|
+
const content = resource.content ?? resource.snippet ?? "";
|
|
49
|
+
const len = content.length;
|
|
50
|
+
let score;
|
|
51
|
+
if (len >= 2000)
|
|
52
|
+
score = 1.0;
|
|
53
|
+
else if (len >= 500)
|
|
54
|
+
score = 0.7;
|
|
55
|
+
else if (len >= 100)
|
|
56
|
+
score = 0.4;
|
|
57
|
+
else
|
|
58
|
+
score = 0.1;
|
|
59
|
+
return { signal: "content_length", score, weight: 0.25 };
|
|
60
|
+
}
|
|
61
|
+
/** Score based on structural elements (headings, lists, code blocks). */
|
|
62
|
+
function scoreStructure(resource) {
|
|
63
|
+
const content = resource.content ?? resource.snippet ?? "";
|
|
64
|
+
let hits = 0;
|
|
65
|
+
if (/^#{1,6}\s/m.test(content))
|
|
66
|
+
hits++;
|
|
67
|
+
if (/^[-*]\s/m.test(content))
|
|
68
|
+
hits++;
|
|
69
|
+
if (/```/.test(content))
|
|
70
|
+
hits++;
|
|
71
|
+
if (/\n\n/.test(content))
|
|
72
|
+
hits++;
|
|
73
|
+
if (/\d+\.\s/.test(content))
|
|
74
|
+
hits++;
|
|
75
|
+
const score = Math.min(hits / 3, 1.0);
|
|
76
|
+
return { signal: "structure", score, weight: 0.2 };
|
|
77
|
+
}
|
|
78
|
+
/** Score based on snippet quality (length, informativeness). */
|
|
79
|
+
function scoreSnippet(resource) {
|
|
80
|
+
const snippet = resource.snippet ?? "";
|
|
81
|
+
const len = snippet.length;
|
|
82
|
+
let score;
|
|
83
|
+
if (len >= 150)
|
|
84
|
+
score = 1.0;
|
|
85
|
+
else if (len >= 80)
|
|
86
|
+
score = 0.7;
|
|
87
|
+
else if (len >= 30)
|
|
88
|
+
score = 0.4;
|
|
89
|
+
else
|
|
90
|
+
score = 0.1;
|
|
91
|
+
// Bonus for snippets that read like informative prose
|
|
92
|
+
if (/\b(because|therefore|however|specifically|according)\b/i.test(snippet)) {
|
|
93
|
+
score = Math.min(score + 0.15, 1.0);
|
|
94
|
+
}
|
|
95
|
+
return { signal: "snippet_quality", score, weight: 0.2 };
|
|
96
|
+
}
|
|
97
|
+
/** Score based on URL quality signals (trusted domain, protocol, path depth). */
|
|
98
|
+
function scoreUrlQuality(resource) {
|
|
99
|
+
const domain = extractDomain(resource.url);
|
|
100
|
+
let score = 0.5; // neutral baseline
|
|
101
|
+
if (TRUSTED_DOMAINS.has(domain)) {
|
|
102
|
+
score = 0.9;
|
|
103
|
+
}
|
|
104
|
+
// HTTPS bonus (applied before penalty so penalty dominates)
|
|
105
|
+
if (resource.url.startsWith("https://")) {
|
|
106
|
+
score = Math.min(score + 0.05, 1.0);
|
|
107
|
+
}
|
|
108
|
+
if (LOW_QUALITY_PATTERNS.some((p) => p.test(resource.url))) {
|
|
109
|
+
score = Math.max(score - 0.4, 0);
|
|
110
|
+
}
|
|
111
|
+
return { signal: "url_quality", score, weight: 0.2 };
|
|
112
|
+
}
|
|
113
|
+
/** Score based on title quality. */
|
|
114
|
+
function scoreTitleQuality(resource) {
|
|
115
|
+
const title = resource.title ?? "";
|
|
116
|
+
let score = 0.5;
|
|
117
|
+
if (title.length >= 20 && title.length <= 120)
|
|
118
|
+
score = 0.8;
|
|
119
|
+
else if (title.length >= 10)
|
|
120
|
+
score = 0.6;
|
|
121
|
+
else
|
|
122
|
+
score = 0.2;
|
|
123
|
+
// Penalise clickbait patterns
|
|
124
|
+
if (/you won't believe|shocking|😱|🔥/i.test(title)) {
|
|
125
|
+
score = Math.max(score - 0.3, 0);
|
|
126
|
+
}
|
|
127
|
+
return { signal: "title_quality", score, weight: 0.15 };
|
|
128
|
+
}
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Main vetter
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
/**
|
|
133
|
+
* Vet a resource for quality using content-based heuristics.
|
|
134
|
+
*
|
|
135
|
+
* @param resource - A web search result to evaluate.
|
|
136
|
+
* @param _modelProvider - Reserved for future LLM-enhanced vetting (unused).
|
|
137
|
+
* @param config - Optional thresholds for accept/reject.
|
|
138
|
+
* @returns A VetResult with the quality score, signals, and recommendation.
|
|
139
|
+
*/
|
|
140
|
+
export async function vetResource(resource, _modelProvider, config) {
|
|
141
|
+
const qualityThreshold = config?.qualityThreshold ?? DEFAULT_QUALITY_THRESHOLD;
|
|
142
|
+
const acceptThreshold = config?.acceptThreshold ?? DEFAULT_ACCEPT_THRESHOLD;
|
|
143
|
+
const signals = [
|
|
144
|
+
scoreContentLength(resource),
|
|
145
|
+
scoreStructure(resource),
|
|
146
|
+
scoreSnippet(resource),
|
|
147
|
+
scoreUrlQuality(resource),
|
|
148
|
+
scoreTitleQuality(resource),
|
|
149
|
+
];
|
|
150
|
+
// Weighted average
|
|
151
|
+
const totalWeight = signals.reduce((sum, s) => sum + s.weight, 0);
|
|
152
|
+
const qualityScore = totalWeight > 0
|
|
153
|
+
? signals.reduce((sum, s) => sum + s.score * s.weight, 0) / totalWeight
|
|
154
|
+
: 0;
|
|
155
|
+
let recommendation;
|
|
156
|
+
let reason;
|
|
157
|
+
if (qualityScore >= acceptThreshold) {
|
|
158
|
+
recommendation = "accept";
|
|
159
|
+
reason = "Resource meets quality standards";
|
|
160
|
+
}
|
|
161
|
+
else if (qualityScore >= qualityThreshold) {
|
|
162
|
+
recommendation = "review";
|
|
163
|
+
reason = "Resource quality is borderline — manual review recommended";
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
recommendation = "reject";
|
|
167
|
+
reason = "Resource quality below threshold";
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
url: resource.url,
|
|
171
|
+
qualityScore: Math.round(qualityScore * 1000) / 1000,
|
|
172
|
+
signals,
|
|
173
|
+
recommendation,
|
|
174
|
+
reason,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vetter/index.ts"],"names":[],"mappings":"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"}
|