@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,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure functions for time-based confidence erosion.
|
|
3
|
+
*
|
|
4
|
+
* Confidence decays linearly over time but never drops below a configured floor.
|
|
5
|
+
* Decay is computed at read time — stored confidence only changes on verification
|
|
6
|
+
* or contradiction events.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Calculate the number of days elapsed between two ISO 8601 timestamps.
|
|
10
|
+
* Returns 0 if end is before start.
|
|
11
|
+
*/
|
|
12
|
+
export function daysElapsed(start, now) {
|
|
13
|
+
const ms = new Date(now).getTime() - new Date(start).getTime();
|
|
14
|
+
return Math.max(0, ms / (1000 * 60 * 60 * 24));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Compute current confidence after applying linear time decay.
|
|
18
|
+
*
|
|
19
|
+
* Formula: confidence = max(minConfidence, storedConfidence - (daysElapsed * erosionRate))
|
|
20
|
+
*
|
|
21
|
+
* @param storedConfidence - The confidence value stored in the database
|
|
22
|
+
* @param lastVerifiedAt - ISO 8601 timestamp of last verification
|
|
23
|
+
* @param erosionRate - Daily decay rate (e.g. 0.05 = 5% per day)
|
|
24
|
+
* @param minConfidence - Confidence floor (values never go below this)
|
|
25
|
+
* @param now - Current time as ISO 8601 string
|
|
26
|
+
*/
|
|
27
|
+
export function computeConfidence(storedConfidence, lastVerifiedAt, erosionRate, minConfidence, now) {
|
|
28
|
+
const days = daysElapsed(lastVerifiedAt, now);
|
|
29
|
+
const decayed = storedConfidence - days * erosionRate;
|
|
30
|
+
return Math.max(minConfidence, decayed);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Compute confidence after applying a contradiction drop.
|
|
34
|
+
*
|
|
35
|
+
* @param currentConfidence - Current confidence (before drop)
|
|
36
|
+
* @param severity - Amount to subtract (e.g. 0.3 for a major contradiction)
|
|
37
|
+
* @param minConfidence - Confidence floor
|
|
38
|
+
*/
|
|
39
|
+
export function applyContradiction(currentConfidence, severity, minConfidence) {
|
|
40
|
+
return Math.max(minConfidence, currentConfidence - severity);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=erosion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erosion.js","sourceRoot":"","sources":["../../src/confidence/erosion.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,GAAW;IACpD,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,gBAAwB,EACxB,cAAsB,EACtB,WAAmB,EACnB,aAAqB,EACrB,GAAW;IAEX,MAAM,IAAI,GAAG,WAAW,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,gBAAgB,GAAG,IAAI,GAAG,WAAW,CAAC;IACtD,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,iBAAyB,EACzB,QAAgB,EAChB,aAAqB;IAErB,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,iBAAiB,GAAG,QAAQ,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confidence System — hybrid erosion with time decay + event-triggered drops.
|
|
3
|
+
*
|
|
4
|
+
* Knowledge confidence decays linearly over time (computed at read time) and
|
|
5
|
+
* can be further reduced by contradiction events. Verification resets the
|
|
6
|
+
* clock and restores confidence.
|
|
7
|
+
*/
|
|
8
|
+
import type { ConfidenceConfig, RefreshCandidate } from "./types.js";
|
|
9
|
+
export type { ConfidenceConfig, RefreshCandidate } from "./types.js";
|
|
10
|
+
export { computeConfidence, daysElapsed, applyContradiction } from "./erosion.js";
|
|
11
|
+
/**
|
|
12
|
+
* Store a ConfidenceConfig in the settings table.
|
|
13
|
+
* Merges with defaults so callers can provide partial overrides.
|
|
14
|
+
*/
|
|
15
|
+
export declare function setConfidenceConfig(config: Partial<ConfidenceConfig>): void;
|
|
16
|
+
/**
|
|
17
|
+
* Retrieve the stored ConfidenceConfig, falling back to defaults.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getConfidenceConfig(): ConfidenceConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Get the current (time-decayed) confidence for an entry.
|
|
22
|
+
*
|
|
23
|
+
* Returns undefined if the entry does not exist.
|
|
24
|
+
* The stored confidence value is NOT mutated — decay is computed at read time.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getConfidence(category: string, slug: string, now?: string): number | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Record a verification — resets last_verified_at to now and restores
|
|
29
|
+
* confidence to the configured initial_confidence (or a custom value).
|
|
30
|
+
*/
|
|
31
|
+
export declare function recordVerification(category: string, slug: string, confidence?: number, now?: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Record a contradiction — immediately drops stored confidence by severity.
|
|
34
|
+
* The drop is applied to the stored value (not the time-decayed computed value).
|
|
35
|
+
*/
|
|
36
|
+
export declare function recordContradiction(category: string, slug: string, severity: number, now?: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Return entries whose computed (time-decayed) confidence is below the
|
|
39
|
+
* refresh threshold, ordered by confidence ascending (most stale first).
|
|
40
|
+
*/
|
|
41
|
+
export declare function getRefreshCandidates(limit?: number, now?: string): RefreshCandidate[];
|
|
42
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/confidence/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAsClF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAO3E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAQtD;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAmBpB;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,GAAG,CAAC,EAAE,MAAM,GACX,IAAI,CAiBN;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,GACX,IAAI,CAmBN;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,CAAC,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,MAAM,GACX,gBAAgB,EAAE,CAqDpB"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confidence System — hybrid erosion with time decay + event-triggered drops.
|
|
3
|
+
*
|
|
4
|
+
* Knowledge confidence decays linearly over time (computed at read time) and
|
|
5
|
+
* can be further reduced by contradiction events. Verification resets the
|
|
6
|
+
* clock and restores confidence.
|
|
7
|
+
*/
|
|
8
|
+
import { getDb } from "../metadata/index.js";
|
|
9
|
+
import { computeConfidence, applyContradiction } from "./erosion.js";
|
|
10
|
+
export { computeConfidence, daysElapsed, applyContradiction } from "./erosion.js";
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Settings table bootstrap
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
const SETTINGS_TABLE_SQL = `
|
|
15
|
+
CREATE TABLE IF NOT EXISTS cq_settings (
|
|
16
|
+
key TEXT PRIMARY KEY,
|
|
17
|
+
value TEXT NOT NULL
|
|
18
|
+
);
|
|
19
|
+
`;
|
|
20
|
+
const CONFIG_KEY = "confidence_config";
|
|
21
|
+
/** Ensure the settings table exists. Called lazily on first use. */
|
|
22
|
+
function ensureSettingsTable() {
|
|
23
|
+
const db = getDb();
|
|
24
|
+
if (!db)
|
|
25
|
+
throw new Error("Metadata DB not initialised — call initMetadataDb first");
|
|
26
|
+
db.exec(SETTINGS_TABLE_SQL);
|
|
27
|
+
}
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Default config
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
const DEFAULT_CONFIG = {
|
|
32
|
+
erosion_rates: {},
|
|
33
|
+
default_rate: 0.02,
|
|
34
|
+
min_confidence: 0.1,
|
|
35
|
+
refresh_threshold: 0.4,
|
|
36
|
+
initial_confidence: 0.8,
|
|
37
|
+
};
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Config storage
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
/**
|
|
42
|
+
* Store a ConfidenceConfig in the settings table.
|
|
43
|
+
* Merges with defaults so callers can provide partial overrides.
|
|
44
|
+
*/
|
|
45
|
+
export function setConfidenceConfig(config) {
|
|
46
|
+
ensureSettingsTable();
|
|
47
|
+
const db = getDb();
|
|
48
|
+
const merged = { ...DEFAULT_CONFIG, ...config };
|
|
49
|
+
db.prepare("INSERT INTO cq_settings (key, value) VALUES (?, ?) ON CONFLICT (key) DO UPDATE SET value = ?").run(CONFIG_KEY, JSON.stringify(merged), JSON.stringify(merged));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Retrieve the stored ConfidenceConfig, falling back to defaults.
|
|
53
|
+
*/
|
|
54
|
+
export function getConfidenceConfig() {
|
|
55
|
+
ensureSettingsTable();
|
|
56
|
+
const db = getDb();
|
|
57
|
+
const row = db.prepare("SELECT value FROM cq_settings WHERE key = ?").get(CONFIG_KEY);
|
|
58
|
+
if (!row)
|
|
59
|
+
return { ...DEFAULT_CONFIG };
|
|
60
|
+
return JSON.parse(row.value);
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Confidence reads
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
/**
|
|
66
|
+
* Get the current (time-decayed) confidence for an entry.
|
|
67
|
+
*
|
|
68
|
+
* Returns undefined if the entry does not exist.
|
|
69
|
+
* The stored confidence value is NOT mutated — decay is computed at read time.
|
|
70
|
+
*/
|
|
71
|
+
export function getConfidence(category, slug, now) {
|
|
72
|
+
const db = getDb();
|
|
73
|
+
if (!db)
|
|
74
|
+
throw new Error("Metadata DB not initialised — call initMetadataDb first");
|
|
75
|
+
const row = db
|
|
76
|
+
.prepare("SELECT confidence, last_verified_at, erosion_rate FROM knowledge_meta WHERE category = ? AND slug = ?")
|
|
77
|
+
.get(category, slug);
|
|
78
|
+
if (!row)
|
|
79
|
+
return undefined;
|
|
80
|
+
const config = getConfidenceConfig();
|
|
81
|
+
const erosionRate = row.erosion_rate > 0
|
|
82
|
+
? row.erosion_rate
|
|
83
|
+
: (config.erosion_rates[category] ?? config.default_rate);
|
|
84
|
+
const currentTime = now ?? new Date().toISOString();
|
|
85
|
+
return computeConfidence(row.confidence, row.last_verified_at, erosionRate, config.min_confidence, currentTime);
|
|
86
|
+
}
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Confidence mutations
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
/**
|
|
91
|
+
* Record a verification — resets last_verified_at to now and restores
|
|
92
|
+
* confidence to the configured initial_confidence (or a custom value).
|
|
93
|
+
*/
|
|
94
|
+
export function recordVerification(category, slug, confidence, now) {
|
|
95
|
+
const db = getDb();
|
|
96
|
+
if (!db)
|
|
97
|
+
throw new Error("Metadata DB not initialised — call initMetadataDb first");
|
|
98
|
+
const config = getConfidenceConfig();
|
|
99
|
+
const newConfidence = confidence ?? config.initial_confidence;
|
|
100
|
+
const currentTime = now ?? new Date().toISOString();
|
|
101
|
+
const result = db
|
|
102
|
+
.prepare("UPDATE knowledge_meta SET confidence = ?, last_verified_at = ?, updated_at = ? WHERE category = ? AND slug = ?")
|
|
103
|
+
.run(newConfidence, currentTime, currentTime, category, slug);
|
|
104
|
+
if (result.changes === 0) {
|
|
105
|
+
throw new Error(`Entry not found: ${category}/${slug}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Record a contradiction — immediately drops stored confidence by severity.
|
|
110
|
+
* The drop is applied to the stored value (not the time-decayed computed value).
|
|
111
|
+
*/
|
|
112
|
+
export function recordContradiction(category, slug, severity, now) {
|
|
113
|
+
const db = getDb();
|
|
114
|
+
if (!db)
|
|
115
|
+
throw new Error("Metadata DB not initialised — call initMetadataDb first");
|
|
116
|
+
const config = getConfidenceConfig();
|
|
117
|
+
const currentTime = now ?? new Date().toISOString();
|
|
118
|
+
const row = db
|
|
119
|
+
.prepare("SELECT confidence FROM knowledge_meta WHERE category = ? AND slug = ?")
|
|
120
|
+
.get(category, slug);
|
|
121
|
+
if (!row) {
|
|
122
|
+
throw new Error(`Entry not found: ${category}/${slug}`);
|
|
123
|
+
}
|
|
124
|
+
const newConfidence = applyContradiction(row.confidence, severity, config.min_confidence);
|
|
125
|
+
db.prepare("UPDATE knowledge_meta SET confidence = ?, updated_at = ? WHERE category = ? AND slug = ?").run(newConfidence, currentTime, category, slug);
|
|
126
|
+
}
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Refresh candidates
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
/**
|
|
131
|
+
* Return entries whose computed (time-decayed) confidence is below the
|
|
132
|
+
* refresh threshold, ordered by confidence ascending (most stale first).
|
|
133
|
+
*/
|
|
134
|
+
export function getRefreshCandidates(limit, now) {
|
|
135
|
+
const db = getDb();
|
|
136
|
+
if (!db)
|
|
137
|
+
throw new Error("Metadata DB not initialised — call initMetadataDb first");
|
|
138
|
+
const config = getConfidenceConfig();
|
|
139
|
+
const currentTime = now ?? new Date().toISOString();
|
|
140
|
+
const rows = db
|
|
141
|
+
.prepare("SELECT slug, category, title, confidence, last_verified_at, erosion_rate FROM knowledge_meta")
|
|
142
|
+
.all();
|
|
143
|
+
const candidates = [];
|
|
144
|
+
for (const row of rows) {
|
|
145
|
+
const erosionRate = row.erosion_rate > 0
|
|
146
|
+
? row.erosion_rate
|
|
147
|
+
: (config.erosion_rates[row.category] ?? config.default_rate);
|
|
148
|
+
const computed = computeConfidence(row.confidence, row.last_verified_at, erosionRate, config.min_confidence, currentTime);
|
|
149
|
+
if (computed < config.refresh_threshold) {
|
|
150
|
+
candidates.push({
|
|
151
|
+
category: row.category,
|
|
152
|
+
slug: row.slug,
|
|
153
|
+
title: row.title,
|
|
154
|
+
stored_confidence: row.confidence,
|
|
155
|
+
computed_confidence: computed,
|
|
156
|
+
last_verified_at: row.last_verified_at,
|
|
157
|
+
erosion_rate: erosionRate,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Sort by computed confidence ascending (most stale first)
|
|
162
|
+
candidates.sort((a, b) => a.computed_confidence - b.computed_confidence);
|
|
163
|
+
if (limit !== undefined && limit > 0) {
|
|
164
|
+
return candidates.slice(0, limit);
|
|
165
|
+
}
|
|
166
|
+
return candidates;
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/confidence/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confidence system type definitions.
|
|
3
|
+
*/
|
|
4
|
+
/** Per-category erosion rates and global confidence thresholds. */
|
|
5
|
+
export interface ConfidenceConfig {
|
|
6
|
+
/** Map of category name to daily erosion rate (e.g. { trends: 0.05, brand: 0.005 }). */
|
|
7
|
+
erosion_rates: Record<string, number>;
|
|
8
|
+
/** Fallback daily erosion rate when category has no specific rate. */
|
|
9
|
+
default_rate: number;
|
|
10
|
+
/** Confidence floor — values never decay below this. Default 0.1. */
|
|
11
|
+
min_confidence: number;
|
|
12
|
+
/** Entries below this threshold are refresh candidates. Default 0.4. */
|
|
13
|
+
refresh_threshold: number;
|
|
14
|
+
/** Confidence assigned to newly indexed entries. Default 0.8. */
|
|
15
|
+
initial_confidence: number;
|
|
16
|
+
}
|
|
17
|
+
/** An entry whose computed confidence is below the refresh threshold. */
|
|
18
|
+
export interface RefreshCandidate {
|
|
19
|
+
category: string;
|
|
20
|
+
slug: string;
|
|
21
|
+
title: string;
|
|
22
|
+
/** The stored (un-decayed) confidence value. */
|
|
23
|
+
stored_confidence: number;
|
|
24
|
+
/** The computed confidence after applying time decay. */
|
|
25
|
+
computed_confidence: number;
|
|
26
|
+
last_verified_at: string;
|
|
27
|
+
erosion_rate: number;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/confidence/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,mEAAmE;AACnE,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iEAAiE;IACjE,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yDAAyD;IACzD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/confidence/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"curiosity.test.d.ts","sourceRoot":"","sources":["../../../src/curiosity/__tests__/curiosity.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { initMetadataDb, closeDb, getDb } from "../../metadata/index.js";
|
|
3
|
+
import { initCuriosityQueue, addCuriosity, fetchPending, getItem, markInProgress, markCompleted, markFailed, dismiss, countByStatus, pruneFailed, levenshtein, normalizedSimilarity, isDuplicate, } from "../index.js";
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Helpers
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
function makeInput(overrides = {}) {
|
|
8
|
+
return {
|
|
9
|
+
question: "Why does latency spike after deploys?",
|
|
10
|
+
context: "Observed 3x latency increase post-deploy",
|
|
11
|
+
source: "observation",
|
|
12
|
+
priority: 5,
|
|
13
|
+
...overrides,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Setup / Teardown
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
initMetadataDb(":memory:");
|
|
21
|
+
initCuriosityQueue();
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
closeDb();
|
|
25
|
+
});
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Levenshtein / Dedup
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
describe("levenshtein", () => {
|
|
30
|
+
it("returns 0 for identical strings", () => {
|
|
31
|
+
expect(levenshtein("hello", "hello")).toBe(0);
|
|
32
|
+
});
|
|
33
|
+
it("returns length of other string when one is empty", () => {
|
|
34
|
+
expect(levenshtein("", "abc")).toBe(3);
|
|
35
|
+
expect(levenshtein("abc", "")).toBe(3);
|
|
36
|
+
});
|
|
37
|
+
it("computes correct edit distance", () => {
|
|
38
|
+
expect(levenshtein("kitten", "sitting")).toBe(3);
|
|
39
|
+
expect(levenshtein("saturday", "sunday")).toBe(3);
|
|
40
|
+
});
|
|
41
|
+
it("returns 0 for two empty strings", () => {
|
|
42
|
+
expect(levenshtein("", "")).toBe(0);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
describe("normalizedSimilarity", () => {
|
|
46
|
+
it("returns 1 for identical strings", () => {
|
|
47
|
+
expect(normalizedSimilarity("hello", "hello")).toBe(1);
|
|
48
|
+
});
|
|
49
|
+
it("returns 1 for two empty strings", () => {
|
|
50
|
+
expect(normalizedSimilarity("", "")).toBe(1);
|
|
51
|
+
});
|
|
52
|
+
it("returns 0 for completely different single chars", () => {
|
|
53
|
+
expect(normalizedSimilarity("a", "b")).toBe(0);
|
|
54
|
+
});
|
|
55
|
+
it("returns a value between 0 and 1", () => {
|
|
56
|
+
const sim = normalizedSimilarity("kitten", "sitting");
|
|
57
|
+
expect(sim).toBeGreaterThan(0);
|
|
58
|
+
expect(sim).toBeLessThan(1);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe("isDuplicate", () => {
|
|
62
|
+
it("detects near-identical questions", () => {
|
|
63
|
+
expect(isDuplicate("why does latency spike", ["why does latency spike?"])).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
it("allows sufficiently different questions", () => {
|
|
66
|
+
expect(isDuplicate("why does latency spike", ["what is the meaning of life"])).toBe(false);
|
|
67
|
+
});
|
|
68
|
+
it("is case-insensitive", () => {
|
|
69
|
+
expect(isDuplicate("WHY DOES LATENCY SPIKE", ["why does latency spike"])).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
it("normalizes whitespace", () => {
|
|
72
|
+
expect(isDuplicate("why does latency spike", ["why does latency spike"])).toBe(true);
|
|
73
|
+
});
|
|
74
|
+
it("returns false for empty existing list", () => {
|
|
75
|
+
expect(isDuplicate("anything", [])).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// addCuriosity
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
describe("addCuriosity", () => {
|
|
82
|
+
it("adds an item and returns it with an id", () => {
|
|
83
|
+
const item = addCuriosity(makeInput());
|
|
84
|
+
expect(item).not.toBeNull();
|
|
85
|
+
expect(item.id).toBeGreaterThan(0);
|
|
86
|
+
expect(item.question).toBe("Why does latency spike after deploys?");
|
|
87
|
+
expect(item.status).toBe("pending");
|
|
88
|
+
expect(item.source).toBe("observation");
|
|
89
|
+
expect(item.priority).toBe(5);
|
|
90
|
+
expect(item.error).toBeNull();
|
|
91
|
+
});
|
|
92
|
+
it("rejects duplicate pending questions (high similarity)", () => {
|
|
93
|
+
addCuriosity(makeInput());
|
|
94
|
+
// Nearly identical — only punctuation difference
|
|
95
|
+
const dup = addCuriosity(makeInput({ question: "Why does latency spike after deploys" }));
|
|
96
|
+
expect(dup).toBeNull();
|
|
97
|
+
});
|
|
98
|
+
it("allows different questions", () => {
|
|
99
|
+
addCuriosity(makeInput());
|
|
100
|
+
const different = addCuriosity(makeInput({ question: "How does caching affect throughput?" }));
|
|
101
|
+
expect(different).not.toBeNull();
|
|
102
|
+
});
|
|
103
|
+
it("throws on invalid priority (< 1)", () => {
|
|
104
|
+
expect(() => addCuriosity(makeInput({ priority: 0 }))).toThrow("Priority must be between 1 and 10");
|
|
105
|
+
});
|
|
106
|
+
it("throws on invalid priority (> 10)", () => {
|
|
107
|
+
expect(() => addCuriosity(makeInput({ priority: 11 }))).toThrow("Priority must be between 1 and 10");
|
|
108
|
+
});
|
|
109
|
+
it("does not dedup against non-pending items", () => {
|
|
110
|
+
const item = addCuriosity(makeInput());
|
|
111
|
+
markCompleted(item.id);
|
|
112
|
+
// Same question, but original is completed — should be allowed
|
|
113
|
+
const second = addCuriosity(makeInput());
|
|
114
|
+
expect(second).not.toBeNull();
|
|
115
|
+
});
|
|
116
|
+
it("accepts all valid source types", () => {
|
|
117
|
+
const sources = [
|
|
118
|
+
"observation",
|
|
119
|
+
"outcome_gap",
|
|
120
|
+
"trend_detection",
|
|
121
|
+
"knowledge_gap",
|
|
122
|
+
"conversation_insight",
|
|
123
|
+
];
|
|
124
|
+
for (const source of sources) {
|
|
125
|
+
const item = addCuriosity(makeInput({ question: `Question about ${source}`, source }));
|
|
126
|
+
expect(item).not.toBeNull();
|
|
127
|
+
expect(item.source).toBe(source);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
it("throws if db not initialised", () => {
|
|
131
|
+
closeDb();
|
|
132
|
+
expect(() => addCuriosity(makeInput())).toThrow("Database not initialised");
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
// fetchPending
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
describe("fetchPending", () => {
|
|
139
|
+
it("returns items ordered by priority DESC, created_at ASC", () => {
|
|
140
|
+
addCuriosity(makeInput({ question: "Low priority old", priority: 1 }));
|
|
141
|
+
addCuriosity(makeInput({ question: "High priority", priority: 10 }));
|
|
142
|
+
addCuriosity(makeInput({ question: "Medium priority", priority: 5 }));
|
|
143
|
+
const items = fetchPending(10);
|
|
144
|
+
expect(items).toHaveLength(3);
|
|
145
|
+
expect(items[0].question).toBe("High priority");
|
|
146
|
+
expect(items[1].question).toBe("Medium priority");
|
|
147
|
+
expect(items[2].question).toBe("Low priority old");
|
|
148
|
+
});
|
|
149
|
+
it("respects the limit parameter", () => {
|
|
150
|
+
addCuriosity(makeInput({ question: "Q1", priority: 5 }));
|
|
151
|
+
addCuriosity(makeInput({ question: "Q2", priority: 3 }));
|
|
152
|
+
addCuriosity(makeInput({ question: "Q3", priority: 1 }));
|
|
153
|
+
const items = fetchPending(2);
|
|
154
|
+
expect(items).toHaveLength(2);
|
|
155
|
+
});
|
|
156
|
+
it("excludes non-pending items", () => {
|
|
157
|
+
const item = addCuriosity(makeInput());
|
|
158
|
+
markInProgress(item.id);
|
|
159
|
+
expect(fetchPending(10)).toHaveLength(0);
|
|
160
|
+
});
|
|
161
|
+
it("returns empty array when queue is empty", () => {
|
|
162
|
+
expect(fetchPending(10)).toHaveLength(0);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// Status transitions
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
describe("status transitions", () => {
|
|
169
|
+
it("markInProgress sets status to in_progress", () => {
|
|
170
|
+
const item = addCuriosity(makeInput());
|
|
171
|
+
markInProgress(item.id);
|
|
172
|
+
const updated = getItem(item.id);
|
|
173
|
+
expect(updated.status).toBe("in_progress");
|
|
174
|
+
expect(updated.updated_at >= item.updated_at).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
it("markCompleted sets status to completed", () => {
|
|
177
|
+
const item = addCuriosity(makeInput());
|
|
178
|
+
markCompleted(item.id);
|
|
179
|
+
expect(getItem(item.id).status).toBe("completed");
|
|
180
|
+
});
|
|
181
|
+
it("markFailed sets status and error message", () => {
|
|
182
|
+
const item = addCuriosity(makeInput());
|
|
183
|
+
markFailed(item.id, "API timeout");
|
|
184
|
+
const updated = getItem(item.id);
|
|
185
|
+
expect(updated.status).toBe("failed");
|
|
186
|
+
expect(updated.error).toBe("API timeout");
|
|
187
|
+
});
|
|
188
|
+
it("dismiss sets status to dismissed", () => {
|
|
189
|
+
const item = addCuriosity(makeInput());
|
|
190
|
+
dismiss(item.id);
|
|
191
|
+
expect(getItem(item.id).status).toBe("dismissed");
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
// getItem
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
describe("getItem", () => {
|
|
198
|
+
it("returns undefined for non-existent id", () => {
|
|
199
|
+
expect(getItem(999)).toBeUndefined();
|
|
200
|
+
});
|
|
201
|
+
it("returns the full item", () => {
|
|
202
|
+
const created = addCuriosity(makeInput());
|
|
203
|
+
const fetched = getItem(created.id);
|
|
204
|
+
expect(fetched.id).toBe(created.id);
|
|
205
|
+
expect(fetched.question).toBe(created.question);
|
|
206
|
+
expect(fetched.context).toBe(created.context);
|
|
207
|
+
expect(fetched.source).toBe(created.source);
|
|
208
|
+
expect(fetched.priority).toBe(created.priority);
|
|
209
|
+
expect(fetched.status).toBe("pending");
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
// countByStatus
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
describe("countByStatus", () => {
|
|
216
|
+
it("returns zero counts when queue is empty", () => {
|
|
217
|
+
const counts = countByStatus();
|
|
218
|
+
expect(counts.pending).toBe(0);
|
|
219
|
+
expect(counts.in_progress).toBe(0);
|
|
220
|
+
expect(counts.completed).toBe(0);
|
|
221
|
+
expect(counts.failed).toBe(0);
|
|
222
|
+
expect(counts.dismissed).toBe(0);
|
|
223
|
+
});
|
|
224
|
+
it("counts items per status correctly", () => {
|
|
225
|
+
const a = addCuriosity(makeInput({ question: "Q1", priority: 5 }));
|
|
226
|
+
const b = addCuriosity(makeInput({ question: "Q2", priority: 3 }));
|
|
227
|
+
addCuriosity(makeInput({ question: "Q3", priority: 1 }));
|
|
228
|
+
markCompleted(a.id);
|
|
229
|
+
markFailed(b.id, "err");
|
|
230
|
+
const counts = countByStatus();
|
|
231
|
+
expect(counts.pending).toBe(1);
|
|
232
|
+
expect(counts.completed).toBe(1);
|
|
233
|
+
expect(counts.failed).toBe(1);
|
|
234
|
+
expect(counts.in_progress).toBe(0);
|
|
235
|
+
expect(counts.dismissed).toBe(0);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
// pruneFailed
|
|
240
|
+
// ---------------------------------------------------------------------------
|
|
241
|
+
describe("pruneFailed", () => {
|
|
242
|
+
it("removes failed items older than threshold", () => {
|
|
243
|
+
const item = addCuriosity(makeInput());
|
|
244
|
+
markFailed(item.id, "timeout");
|
|
245
|
+
// Backdate the created_at to 10 days ago
|
|
246
|
+
const db = getDb();
|
|
247
|
+
const oldDate = new Date(Date.now() - 10 * 86_400_000).toISOString();
|
|
248
|
+
db.prepare("UPDATE curiosity_queue SET created_at = ? WHERE id = ?").run(oldDate, item.id);
|
|
249
|
+
const removed = pruneFailed(7);
|
|
250
|
+
expect(removed).toBe(1);
|
|
251
|
+
expect(getItem(item.id)).toBeUndefined();
|
|
252
|
+
});
|
|
253
|
+
it("does not remove recent failed items", () => {
|
|
254
|
+
const item = addCuriosity(makeInput());
|
|
255
|
+
markFailed(item.id, "timeout");
|
|
256
|
+
const removed = pruneFailed(7);
|
|
257
|
+
expect(removed).toBe(0);
|
|
258
|
+
expect(getItem(item.id)).toBeDefined();
|
|
259
|
+
});
|
|
260
|
+
it("does not remove non-failed items regardless of age", () => {
|
|
261
|
+
const item = addCuriosity(makeInput());
|
|
262
|
+
// Backdate but keep as pending
|
|
263
|
+
const db = getDb();
|
|
264
|
+
const oldDate = new Date(Date.now() - 30 * 86_400_000).toISOString();
|
|
265
|
+
db.prepare("UPDATE curiosity_queue SET created_at = ? WHERE id = ?").run(oldDate, item.id);
|
|
266
|
+
const removed = pruneFailed(7);
|
|
267
|
+
expect(removed).toBe(0);
|
|
268
|
+
});
|
|
269
|
+
it("returns count of removed items", () => {
|
|
270
|
+
for (let i = 0; i < 3; i++) {
|
|
271
|
+
const item = addCuriosity(makeInput({ question: `Fail question ${i}`, priority: 5 }));
|
|
272
|
+
markFailed(item.id, "err");
|
|
273
|
+
}
|
|
274
|
+
const db = getDb();
|
|
275
|
+
const oldDate = new Date(Date.now() - 20 * 86_400_000).toISOString();
|
|
276
|
+
db.prepare("UPDATE curiosity_queue SET created_at = ? WHERE status = 'failed'").run(oldDate);
|
|
277
|
+
expect(pruneFailed(7)).toBe(3);
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
//# sourceMappingURL=curiosity.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"curiosity.test.js","sourceRoot":"","sources":["../../../src/curiosity/__tests__/curiosity.test.ts"],"names":[],"mappings":"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"}
|