@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,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Tracker — runtime context window budget management.
|
|
3
|
+
*
|
|
4
|
+
* Tracks token usage for knowledge entries loaded into an LLM context window.
|
|
5
|
+
* Supports multiple selection strategies for fitting entries within a budget.
|
|
6
|
+
*/
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Helpers
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/** Estimate token count from content length (~4 chars per token). */
|
|
11
|
+
export function estimateTokens(content) {
|
|
12
|
+
return Math.ceil(content.length / 4);
|
|
13
|
+
}
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// TokenTracker
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/**
|
|
18
|
+
* Manages a token budget for loading knowledge entries into a context window.
|
|
19
|
+
*
|
|
20
|
+
* Not backed by SQLite — this is a purely in-memory runtime tracker.
|
|
21
|
+
*/
|
|
22
|
+
export class TokenTracker {
|
|
23
|
+
maxTokens;
|
|
24
|
+
used = 0;
|
|
25
|
+
reserved = new Map();
|
|
26
|
+
constructor(maxTokens) {
|
|
27
|
+
if (maxTokens <= 0) {
|
|
28
|
+
throw new Error("maxTokens must be a positive number");
|
|
29
|
+
}
|
|
30
|
+
this.maxTokens = maxTokens;
|
|
31
|
+
}
|
|
32
|
+
/** Key for deduplication in the reserved map. */
|
|
33
|
+
entryKey(entry) {
|
|
34
|
+
return `${entry.category}/${entry.slug}`;
|
|
35
|
+
}
|
|
36
|
+
/** Current available tokens. */
|
|
37
|
+
get remaining() {
|
|
38
|
+
return this.maxTokens - this.used;
|
|
39
|
+
}
|
|
40
|
+
/** Check whether an entry's content fits in the remaining budget. */
|
|
41
|
+
wouldFit(entry) {
|
|
42
|
+
const tokens = estimateTokens(entry.content);
|
|
43
|
+
return tokens <= this.remaining;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Reserve tokens for an entry, deducting from the remaining budget.
|
|
47
|
+
* Throws if the entry would exceed the budget.
|
|
48
|
+
* No-op if the entry is already reserved.
|
|
49
|
+
*/
|
|
50
|
+
reserve(entry) {
|
|
51
|
+
const key = this.entryKey(entry);
|
|
52
|
+
if (this.reserved.has(key))
|
|
53
|
+
return;
|
|
54
|
+
const tokens = estimateTokens(entry.content);
|
|
55
|
+
if (tokens > this.remaining) {
|
|
56
|
+
throw new Error(`Cannot reserve ${tokens} tokens for "${key}" — only ${this.remaining} remaining`);
|
|
57
|
+
}
|
|
58
|
+
this.reserved.set(key, tokens);
|
|
59
|
+
this.used += tokens;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Release tokens previously reserved for an entry, returning them to the budget.
|
|
63
|
+
* No-op if the entry is not currently reserved.
|
|
64
|
+
*/
|
|
65
|
+
release(entry) {
|
|
66
|
+
const key = this.entryKey(entry);
|
|
67
|
+
const tokens = this.reserved.get(key);
|
|
68
|
+
if (tokens === undefined)
|
|
69
|
+
return;
|
|
70
|
+
this.reserved.delete(key);
|
|
71
|
+
this.used -= tokens;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Select entries that fit within the remaining budget using the given strategy.
|
|
75
|
+
*
|
|
76
|
+
* @param entries - Scored entries to consider.
|
|
77
|
+
* @param strategy - Selection strategy.
|
|
78
|
+
* @returns Entries selected to fit within budget, ordered by strategy priority.
|
|
79
|
+
*/
|
|
80
|
+
selectEntries(entries, strategy) {
|
|
81
|
+
const sorted = this.sortByStrategy([...entries], strategy);
|
|
82
|
+
const selected = [];
|
|
83
|
+
let budget = this.remaining;
|
|
84
|
+
for (const { entry } of sorted) {
|
|
85
|
+
const tokens = estimateTokens(entry.content);
|
|
86
|
+
if (tokens <= budget) {
|
|
87
|
+
selected.push(entry);
|
|
88
|
+
budget -= tokens;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return selected;
|
|
92
|
+
}
|
|
93
|
+
// -------------------------------------------------------------------------
|
|
94
|
+
// Strategy sorting
|
|
95
|
+
// -------------------------------------------------------------------------
|
|
96
|
+
sortByStrategy(entries, strategy) {
|
|
97
|
+
switch (strategy) {
|
|
98
|
+
case "highest_confidence":
|
|
99
|
+
return entries.sort((a, b) => (b.confidence ?? 0) - (a.confidence ?? 0));
|
|
100
|
+
case "most_relevant":
|
|
101
|
+
return entries.sort((a, b) => (b.relevance ?? 0) - (a.relevance ?? 0));
|
|
102
|
+
case "balanced":
|
|
103
|
+
return this.balancedSort(entries);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Balanced strategy: interleave entries from different categories,
|
|
108
|
+
* sorted within each category by a combined confidence + relevance score.
|
|
109
|
+
*/
|
|
110
|
+
balancedSort(entries) {
|
|
111
|
+
// Score each entry by averaging confidence and relevance (whichever are available).
|
|
112
|
+
const scored = entries.map((e) => {
|
|
113
|
+
const c = e.confidence ?? 0;
|
|
114
|
+
const r = e.relevance ?? 0;
|
|
115
|
+
const hasC = e.confidence !== undefined;
|
|
116
|
+
const hasR = e.relevance !== undefined;
|
|
117
|
+
const score = hasC && hasR ? (c + r) / 2 : hasC ? c : hasR ? r : 0;
|
|
118
|
+
return { scored: e, score, category: e.entry.category };
|
|
119
|
+
});
|
|
120
|
+
// Group by category.
|
|
121
|
+
const byCategory = new Map();
|
|
122
|
+
for (const item of scored) {
|
|
123
|
+
const list = byCategory.get(item.category) ?? [];
|
|
124
|
+
list.push(item);
|
|
125
|
+
byCategory.set(item.category, list);
|
|
126
|
+
}
|
|
127
|
+
// Sort each category's entries by score descending.
|
|
128
|
+
for (const list of byCategory.values()) {
|
|
129
|
+
list.sort((a, b) => b.score - a.score);
|
|
130
|
+
}
|
|
131
|
+
// Round-robin across categories.
|
|
132
|
+
const result = [];
|
|
133
|
+
const categoryQueues = [...byCategory.values()];
|
|
134
|
+
// Sort category groups by best score so highest-scoring categories go first.
|
|
135
|
+
categoryQueues.sort((a, b) => (b[0]?.score ?? 0) - (a[0]?.score ?? 0));
|
|
136
|
+
let exhausted = 0;
|
|
137
|
+
const indices = categoryQueues.map(() => 0);
|
|
138
|
+
while (exhausted < categoryQueues.length) {
|
|
139
|
+
for (let i = 0; i < categoryQueues.length; i++) {
|
|
140
|
+
const queue = categoryQueues[i];
|
|
141
|
+
if (indices[i] < queue.length) {
|
|
142
|
+
result.push(queue[indices[i]].scored);
|
|
143
|
+
indices[i]++;
|
|
144
|
+
if (indices[i] >= queue.length)
|
|
145
|
+
exhausted++;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=token-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-tracker.js","sourceRoot":"","sources":["../../src/budget/token-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Budget tracker type definitions.
|
|
3
|
+
*/
|
|
4
|
+
/** Configurable cost defaults and spending limits. */
|
|
5
|
+
export interface BudgetConfig {
|
|
6
|
+
/** Maximum spend per calendar day (UTC), in USD. */
|
|
7
|
+
dailyLimitUsd: number;
|
|
8
|
+
/** Optional lifetime spending cap, in USD. */
|
|
9
|
+
totalLimitUsd?: number;
|
|
10
|
+
/** Estimated cost per web search, in USD. Default 0.03. */
|
|
11
|
+
searchCostUsd: number;
|
|
12
|
+
/** Estimated cost per synthesis call, in USD. Default 0.01. */
|
|
13
|
+
synthesisCostUsd: number;
|
|
14
|
+
/** Estimated cost per vetting call, in USD. Default 0.005. */
|
|
15
|
+
vetCostUsd: number;
|
|
16
|
+
}
|
|
17
|
+
/** Charge type recorded in the research_budget table. */
|
|
18
|
+
export type ChargeType = "search" | "synthesis" | "vetting" | "other";
|
|
19
|
+
/** Result of a budget check — indicates whether a charge is allowed. */
|
|
20
|
+
export interface BudgetCheckResult {
|
|
21
|
+
/** Whether the estimated charge fits within remaining limits. */
|
|
22
|
+
allowed: boolean;
|
|
23
|
+
/** Remaining budget for the current day (UTC). */
|
|
24
|
+
remainingUsd: number;
|
|
25
|
+
/** Amount spent today (UTC). */
|
|
26
|
+
dailyUsedUsd: number;
|
|
27
|
+
/** Lifetime total spent. */
|
|
28
|
+
totalUsedUsd: number;
|
|
29
|
+
/** Human-readable reason when not allowed. */
|
|
30
|
+
reason?: string;
|
|
31
|
+
}
|
|
32
|
+
/** Daily or total budget usage summary. */
|
|
33
|
+
export interface BudgetStatus {
|
|
34
|
+
/** Amount spent in the scope (daily or total). */
|
|
35
|
+
usedUsd: number;
|
|
36
|
+
/** Configured limit for the scope (may be undefined for total if uncapped). */
|
|
37
|
+
limitUsd?: number;
|
|
38
|
+
/** Remaining budget (limitUsd - usedUsd), or undefined if uncapped. */
|
|
39
|
+
remainingUsd?: number;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/budget/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,gBAAgB,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,yDAAyD;AACzD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;AAEtE,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/budget/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confidence.test.d.ts","sourceRoot":"","sources":["../../../src/confidence/__tests__/confidence.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { initMetadataDb, closeDb, getDb, indexEntry } from "../../metadata/index.js";
|
|
3
|
+
import { setConfidenceConfig, getConfidenceConfig, getConfidence, recordVerification, recordContradiction, getRefreshCandidates, computeConfidence, daysElapsed, applyContradiction, } from "../index.js";
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Helpers
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
function makeEntry(overrides = {}) {
|
|
8
|
+
return {
|
|
9
|
+
category: "trends",
|
|
10
|
+
slug: "ai-agents",
|
|
11
|
+
title: "AI Agent Landscape",
|
|
12
|
+
tags: ["ai"],
|
|
13
|
+
created: "2025-01-01T00:00:00.000Z",
|
|
14
|
+
updated: "2025-06-01T00:00:00.000Z",
|
|
15
|
+
content: "AI agents are rapidly evolving.",
|
|
16
|
+
...overrides,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** Return an ISO string offset by the given number of days from a base. */
|
|
20
|
+
function addDays(base, days) {
|
|
21
|
+
const d = new Date(base);
|
|
22
|
+
d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000);
|
|
23
|
+
return d.toISOString();
|
|
24
|
+
}
|
|
25
|
+
const BASE_TIME = "2025-06-01T00:00:00.000Z";
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
initMetadataDb(":memory:");
|
|
28
|
+
});
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
closeDb();
|
|
31
|
+
});
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Pure erosion functions
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
describe("daysElapsed", () => {
|
|
36
|
+
it("returns 0 for same timestamp", () => {
|
|
37
|
+
expect(daysElapsed(BASE_TIME, BASE_TIME)).toBe(0);
|
|
38
|
+
});
|
|
39
|
+
it("computes fractional days", () => {
|
|
40
|
+
const twelveHoursLater = addDays(BASE_TIME, 0.5);
|
|
41
|
+
expect(daysElapsed(BASE_TIME, twelveHoursLater)).toBeCloseTo(0.5, 5);
|
|
42
|
+
});
|
|
43
|
+
it("returns 0 when end is before start", () => {
|
|
44
|
+
const earlier = addDays(BASE_TIME, -1);
|
|
45
|
+
expect(daysElapsed(BASE_TIME, earlier)).toBe(0);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
describe("computeConfidence", () => {
|
|
49
|
+
it("returns stored confidence when no time has elapsed", () => {
|
|
50
|
+
expect(computeConfidence(0.8, BASE_TIME, 0.05, 0.1, BASE_TIME)).toBe(0.8);
|
|
51
|
+
});
|
|
52
|
+
it("decays linearly over time", () => {
|
|
53
|
+
const tenDaysLater = addDays(BASE_TIME, 10);
|
|
54
|
+
// 0.8 - (10 * 0.05) = 0.3
|
|
55
|
+
expect(computeConfidence(0.8, BASE_TIME, 0.05, 0.1, tenDaysLater)).toBeCloseTo(0.3, 10);
|
|
56
|
+
});
|
|
57
|
+
it("enforces minimum confidence floor", () => {
|
|
58
|
+
const thirtyDaysLater = addDays(BASE_TIME, 30);
|
|
59
|
+
// 0.8 - (30 * 0.05) = -0.7 → clamped to 0.1
|
|
60
|
+
expect(computeConfidence(0.8, BASE_TIME, 0.05, 0.1, thirtyDaysLater)).toBe(0.1);
|
|
61
|
+
});
|
|
62
|
+
it("handles zero erosion rate", () => {
|
|
63
|
+
const yearLater = addDays(BASE_TIME, 365);
|
|
64
|
+
expect(computeConfidence(0.8, BASE_TIME, 0, 0.1, yearLater)).toBe(0.8);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
describe("applyContradiction", () => {
|
|
68
|
+
it("drops confidence by severity", () => {
|
|
69
|
+
expect(applyContradiction(0.8, 0.3, 0.1)).toBeCloseTo(0.5, 10);
|
|
70
|
+
});
|
|
71
|
+
it("enforces minimum confidence floor", () => {
|
|
72
|
+
expect(applyContradiction(0.3, 0.5, 0.1)).toBe(0.1);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Config storage
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
describe("setConfidenceConfig / getConfidenceConfig", () => {
|
|
79
|
+
it("returns defaults when no config has been set", () => {
|
|
80
|
+
const config = getConfidenceConfig();
|
|
81
|
+
expect(config.min_confidence).toBe(0.1);
|
|
82
|
+
expect(config.refresh_threshold).toBe(0.4);
|
|
83
|
+
expect(config.initial_confidence).toBe(0.8);
|
|
84
|
+
expect(config.default_rate).toBe(0.02);
|
|
85
|
+
expect(config.erosion_rates).toEqual({});
|
|
86
|
+
});
|
|
87
|
+
it("stores and retrieves a custom config", () => {
|
|
88
|
+
const custom = {
|
|
89
|
+
erosion_rates: { trends: 0.05, brand: 0.005 },
|
|
90
|
+
default_rate: 0.01,
|
|
91
|
+
min_confidence: 0.05,
|
|
92
|
+
refresh_threshold: 0.3,
|
|
93
|
+
initial_confidence: 0.9,
|
|
94
|
+
};
|
|
95
|
+
setConfidenceConfig(custom);
|
|
96
|
+
const config = getConfidenceConfig();
|
|
97
|
+
expect(config.erosion_rates).toEqual({ trends: 0.05, brand: 0.005 });
|
|
98
|
+
expect(config.default_rate).toBe(0.01);
|
|
99
|
+
expect(config.min_confidence).toBe(0.05);
|
|
100
|
+
expect(config.refresh_threshold).toBe(0.3);
|
|
101
|
+
expect(config.initial_confidence).toBe(0.9);
|
|
102
|
+
});
|
|
103
|
+
it("overwrites previous config on re-set", () => {
|
|
104
|
+
setConfidenceConfig({ default_rate: 0.01 });
|
|
105
|
+
setConfidenceConfig({ default_rate: 0.03 });
|
|
106
|
+
expect(getConfidenceConfig().default_rate).toBe(0.03);
|
|
107
|
+
});
|
|
108
|
+
it("merges partial config with defaults", () => {
|
|
109
|
+
setConfidenceConfig({ default_rate: 0.07 });
|
|
110
|
+
const config = getConfidenceConfig();
|
|
111
|
+
expect(config.default_rate).toBe(0.07);
|
|
112
|
+
expect(config.min_confidence).toBe(0.1); // default preserved
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// getConfidence
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
describe("getConfidence", () => {
|
|
119
|
+
it("returns undefined for non-existent entry", () => {
|
|
120
|
+
expect(getConfidence("missing", "nothing")).toBeUndefined();
|
|
121
|
+
});
|
|
122
|
+
it("returns stored confidence when no time has elapsed", () => {
|
|
123
|
+
indexEntry(makeEntry());
|
|
124
|
+
// indexEntry sets confidence to 1.0 and last_verified_at to ~now
|
|
125
|
+
const now = new Date().toISOString();
|
|
126
|
+
const c = getConfidence("trends", "ai-agents", now);
|
|
127
|
+
expect(c).toBeCloseTo(1.0, 1);
|
|
128
|
+
});
|
|
129
|
+
it("applies time decay using category-specific erosion rate", () => {
|
|
130
|
+
setConfidenceConfig({
|
|
131
|
+
erosion_rates: { trends: 0.05 },
|
|
132
|
+
min_confidence: 0.1,
|
|
133
|
+
});
|
|
134
|
+
indexEntry(makeEntry());
|
|
135
|
+
// Simulate 10 days later
|
|
136
|
+
const tenDaysLater = addDays(new Date().toISOString(), 10);
|
|
137
|
+
const c = getConfidence("trends", "ai-agents", tenDaysLater);
|
|
138
|
+
// 1.0 - (10 * 0.05) = 0.5
|
|
139
|
+
expect(c).toBeCloseTo(0.5, 1);
|
|
140
|
+
});
|
|
141
|
+
it("uses default_rate when no category-specific rate exists", () => {
|
|
142
|
+
setConfidenceConfig({
|
|
143
|
+
erosion_rates: {},
|
|
144
|
+
default_rate: 0.1,
|
|
145
|
+
min_confidence: 0.1,
|
|
146
|
+
});
|
|
147
|
+
indexEntry(makeEntry({ category: "misc", slug: "test" }));
|
|
148
|
+
const tenDaysLater = addDays(new Date().toISOString(), 10);
|
|
149
|
+
// 1.0 - (10 * 0.1) = 0.0 → clamped to 0.1
|
|
150
|
+
const c = getConfidence("misc", "test", tenDaysLater);
|
|
151
|
+
expect(c).toBe(0.1);
|
|
152
|
+
});
|
|
153
|
+
it("uses entry-level erosion_rate when set on the row", () => {
|
|
154
|
+
setConfidenceConfig({
|
|
155
|
+
erosion_rates: { trends: 0.05 },
|
|
156
|
+
default_rate: 0.02,
|
|
157
|
+
min_confidence: 0.1,
|
|
158
|
+
});
|
|
159
|
+
indexEntry(makeEntry());
|
|
160
|
+
// Override erosion_rate directly on the row
|
|
161
|
+
const db = getDb();
|
|
162
|
+
db.prepare("UPDATE knowledge_meta SET erosion_rate = 0.2 WHERE slug = 'ai-agents'").run();
|
|
163
|
+
const fiveDaysLater = addDays(new Date().toISOString(), 5);
|
|
164
|
+
// 1.0 - (5 * 0.2) = 0.0 → clamped to 0.1
|
|
165
|
+
const c = getConfidence("trends", "ai-agents", fiveDaysLater);
|
|
166
|
+
expect(c).toBe(0.1);
|
|
167
|
+
});
|
|
168
|
+
it("never returns below min_confidence", () => {
|
|
169
|
+
setConfidenceConfig({ default_rate: 0.5, min_confidence: 0.15 });
|
|
170
|
+
indexEntry(makeEntry());
|
|
171
|
+
const hundredDaysLater = addDays(new Date().toISOString(), 100);
|
|
172
|
+
const c = getConfidence("trends", "ai-agents", hundredDaysLater);
|
|
173
|
+
expect(c).toBe(0.15);
|
|
174
|
+
});
|
|
175
|
+
it("throws if db not initialised", () => {
|
|
176
|
+
closeDb();
|
|
177
|
+
expect(() => getConfidence("a", "b")).toThrow("Metadata DB not initialised");
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
// ---------------------------------------------------------------------------
|
|
181
|
+
// recordVerification
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
describe("recordVerification", () => {
|
|
184
|
+
it("restores confidence to initial_confidence", () => {
|
|
185
|
+
setConfidenceConfig({ initial_confidence: 0.9, default_rate: 0.1, min_confidence: 0.1 });
|
|
186
|
+
indexEntry(makeEntry());
|
|
187
|
+
// Drop confidence via contradiction first
|
|
188
|
+
recordContradiction("trends", "ai-agents", 0.5);
|
|
189
|
+
const now = new Date().toISOString();
|
|
190
|
+
recordVerification("trends", "ai-agents", undefined, now);
|
|
191
|
+
const c = getConfidence("trends", "ai-agents", now);
|
|
192
|
+
expect(c).toBeCloseTo(0.9, 5);
|
|
193
|
+
});
|
|
194
|
+
it("allows custom confidence value", () => {
|
|
195
|
+
indexEntry(makeEntry());
|
|
196
|
+
const now = new Date().toISOString();
|
|
197
|
+
recordVerification("trends", "ai-agents", 0.95, now);
|
|
198
|
+
const c = getConfidence("trends", "ai-agents", now);
|
|
199
|
+
expect(c).toBeCloseTo(0.95, 5);
|
|
200
|
+
});
|
|
201
|
+
it("resets the decay clock (last_verified_at)", () => {
|
|
202
|
+
setConfidenceConfig({ default_rate: 0.1, min_confidence: 0.1 });
|
|
203
|
+
indexEntry(makeEntry());
|
|
204
|
+
// After 5 days, confidence would be 0.5 without verification
|
|
205
|
+
const fiveDaysLater = addDays(new Date().toISOString(), 5);
|
|
206
|
+
// Verify at day 5 — resets the clock
|
|
207
|
+
recordVerification("trends", "ai-agents", undefined, fiveDaysLater);
|
|
208
|
+
// Check at day 5 — should be freshly restored
|
|
209
|
+
const c = getConfidence("trends", "ai-agents", fiveDaysLater);
|
|
210
|
+
expect(c).toBeCloseTo(0.8, 1); // default initial_confidence
|
|
211
|
+
});
|
|
212
|
+
it("throws for non-existent entry", () => {
|
|
213
|
+
expect(() => recordVerification("missing", "nope")).toThrow("Entry not found");
|
|
214
|
+
});
|
|
215
|
+
it("throws if db not initialised", () => {
|
|
216
|
+
closeDb();
|
|
217
|
+
expect(() => recordVerification("a", "b")).toThrow("Metadata DB not initialised");
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
// recordContradiction
|
|
222
|
+
// ---------------------------------------------------------------------------
|
|
223
|
+
describe("recordContradiction", () => {
|
|
224
|
+
it("drops stored confidence by severity amount", () => {
|
|
225
|
+
indexEntry(makeEntry()); // confidence = 1.0
|
|
226
|
+
const now = new Date().toISOString();
|
|
227
|
+
recordContradiction("trends", "ai-agents", 0.3, now);
|
|
228
|
+
const c = getConfidence("trends", "ai-agents", now);
|
|
229
|
+
expect(c).toBeCloseTo(0.7, 5);
|
|
230
|
+
});
|
|
231
|
+
it("enforces min_confidence floor", () => {
|
|
232
|
+
setConfidenceConfig({ min_confidence: 0.15 });
|
|
233
|
+
indexEntry(makeEntry()); // confidence = 1.0
|
|
234
|
+
const now = new Date().toISOString();
|
|
235
|
+
recordContradiction("trends", "ai-agents", 0.95, now);
|
|
236
|
+
const c = getConfidence("trends", "ai-agents", now);
|
|
237
|
+
expect(c).toBe(0.15);
|
|
238
|
+
});
|
|
239
|
+
it("stacks with time decay", () => {
|
|
240
|
+
setConfidenceConfig({ default_rate: 0.05, min_confidence: 0.1 });
|
|
241
|
+
indexEntry(makeEntry()); // confidence = 1.0
|
|
242
|
+
const now = new Date().toISOString();
|
|
243
|
+
// Contradiction drops stored confidence: 1.0 - 0.3 = 0.7
|
|
244
|
+
recordContradiction("trends", "ai-agents", 0.3, now);
|
|
245
|
+
// After 4 more days: 0.7 - (4 * 0.05) = 0.5
|
|
246
|
+
const fourDaysLater = addDays(now, 4);
|
|
247
|
+
const c = getConfidence("trends", "ai-agents", fourDaysLater);
|
|
248
|
+
expect(c).toBeCloseTo(0.5, 1);
|
|
249
|
+
});
|
|
250
|
+
it("throws for non-existent entry", () => {
|
|
251
|
+
expect(() => recordContradiction("missing", "nope", 0.5)).toThrow("Entry not found");
|
|
252
|
+
});
|
|
253
|
+
it("throws if db not initialised", () => {
|
|
254
|
+
closeDb();
|
|
255
|
+
expect(() => recordContradiction("a", "b", 0.5)).toThrow("Metadata DB not initialised");
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
// ---------------------------------------------------------------------------
|
|
259
|
+
// getRefreshCandidates
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
describe("getRefreshCandidates", () => {
|
|
262
|
+
it("returns entries below refresh threshold", () => {
|
|
263
|
+
setConfidenceConfig({
|
|
264
|
+
erosion_rates: { trends: 0.05 },
|
|
265
|
+
default_rate: 0.02,
|
|
266
|
+
refresh_threshold: 0.4,
|
|
267
|
+
min_confidence: 0.1,
|
|
268
|
+
});
|
|
269
|
+
indexEntry(makeEntry({ slug: "fast-decay", category: "trends" }));
|
|
270
|
+
indexEntry(makeEntry({ slug: "slow-decay", category: "brand" }));
|
|
271
|
+
// 15 days later:
|
|
272
|
+
// trends/fast-decay: 1.0 - (15 * 0.05) = 0.25 < 0.4 -> candidate
|
|
273
|
+
// brand/slow-decay: 1.0 - (15 * 0.02) = 0.70 >= 0.4 -> not candidate
|
|
274
|
+
const now = new Date().toISOString();
|
|
275
|
+
const fifteenDaysLater = addDays(now, 15);
|
|
276
|
+
const candidates = getRefreshCandidates(undefined, fifteenDaysLater);
|
|
277
|
+
expect(candidates).toHaveLength(1);
|
|
278
|
+
expect(candidates[0].slug).toBe("fast-decay");
|
|
279
|
+
expect(candidates[0].computed_confidence).toBeCloseTo(0.25, 1);
|
|
280
|
+
});
|
|
281
|
+
it("orders by computed confidence ascending (most stale first)", () => {
|
|
282
|
+
setConfidenceConfig({
|
|
283
|
+
default_rate: 0.05,
|
|
284
|
+
refresh_threshold: 0.5,
|
|
285
|
+
min_confidence: 0.1,
|
|
286
|
+
});
|
|
287
|
+
indexEntry(makeEntry({ slug: "a", category: "c1" }));
|
|
288
|
+
indexEntry(makeEntry({ slug: "b", category: "c2" }));
|
|
289
|
+
// Drop b's stored confidence so it's worse off
|
|
290
|
+
recordContradiction("c2", "b", 0.3);
|
|
291
|
+
const now = new Date().toISOString();
|
|
292
|
+
const twelveDaysLater = addDays(now, 12);
|
|
293
|
+
// c1/a: 1.0 - (12 * 0.05) = 0.4 < 0.5
|
|
294
|
+
// c2/b: 0.7 - (12 * 0.05) = 0.1 < 0.5
|
|
295
|
+
const candidates = getRefreshCandidates(undefined, twelveDaysLater);
|
|
296
|
+
expect(candidates.length).toBeGreaterThanOrEqual(2);
|
|
297
|
+
expect(candidates[0].slug).toBe("b"); // lowest first
|
|
298
|
+
});
|
|
299
|
+
it("respects limit parameter", () => {
|
|
300
|
+
setConfidenceConfig({ default_rate: 0.1, refresh_threshold: 0.95, min_confidence: 0.1 });
|
|
301
|
+
indexEntry(makeEntry({ slug: "x", category: "a" }));
|
|
302
|
+
indexEntry(makeEntry({ slug: "y", category: "b" }));
|
|
303
|
+
indexEntry(makeEntry({ slug: "z", category: "c" }));
|
|
304
|
+
// 2 days later: 1.0 - (2 * 0.1) = 0.8 < 0.95, all 3 qualify
|
|
305
|
+
const twoDaysLater = addDays(new Date().toISOString(), 2);
|
|
306
|
+
const candidates = getRefreshCandidates(2, twoDaysLater);
|
|
307
|
+
expect(candidates).toHaveLength(2);
|
|
308
|
+
});
|
|
309
|
+
it("returns empty array when all entries are above threshold", () => {
|
|
310
|
+
setConfidenceConfig({ default_rate: 0.001, refresh_threshold: 0.4 });
|
|
311
|
+
indexEntry(makeEntry());
|
|
312
|
+
const now = new Date().toISOString();
|
|
313
|
+
const candidates = getRefreshCandidates(undefined, now);
|
|
314
|
+
expect(candidates).toHaveLength(0);
|
|
315
|
+
});
|
|
316
|
+
it("includes correct metadata in each candidate", () => {
|
|
317
|
+
setConfidenceConfig({ default_rate: 0.1, refresh_threshold: 0.9, min_confidence: 0.1 });
|
|
318
|
+
indexEntry(makeEntry());
|
|
319
|
+
const twoDaysLater = addDays(new Date().toISOString(), 2);
|
|
320
|
+
const candidates = getRefreshCandidates(undefined, twoDaysLater);
|
|
321
|
+
expect(candidates).toHaveLength(1);
|
|
322
|
+
const c = candidates[0];
|
|
323
|
+
expect(c.category).toBe("trends");
|
|
324
|
+
expect(c.slug).toBe("ai-agents");
|
|
325
|
+
expect(c.title).toBe("AI Agent Landscape");
|
|
326
|
+
expect(c.stored_confidence).toBe(1.0);
|
|
327
|
+
expect(c.computed_confidence).toBeCloseTo(0.8, 1);
|
|
328
|
+
expect(typeof c.last_verified_at).toBe("string");
|
|
329
|
+
expect(typeof c.erosion_rate).toBe("number");
|
|
330
|
+
});
|
|
331
|
+
it("throws if db not initialised", () => {
|
|
332
|
+
closeDb();
|
|
333
|
+
expect(() => getRefreshCandidates()).toThrow("Metadata DB not initialised");
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
//# sourceMappingURL=confidence.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confidence.test.js","sourceRoot":"","sources":["../../../src/confidence/__tests__/confidence.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
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 declare function daysElapsed(start: string, now: string): number;
|
|
13
|
+
/**
|
|
14
|
+
* Compute current confidence after applying linear time decay.
|
|
15
|
+
*
|
|
16
|
+
* Formula: confidence = max(minConfidence, storedConfidence - (daysElapsed * erosionRate))
|
|
17
|
+
*
|
|
18
|
+
* @param storedConfidence - The confidence value stored in the database
|
|
19
|
+
* @param lastVerifiedAt - ISO 8601 timestamp of last verification
|
|
20
|
+
* @param erosionRate - Daily decay rate (e.g. 0.05 = 5% per day)
|
|
21
|
+
* @param minConfidence - Confidence floor (values never go below this)
|
|
22
|
+
* @param now - Current time as ISO 8601 string
|
|
23
|
+
*/
|
|
24
|
+
export declare function computeConfidence(storedConfidence: number, lastVerifiedAt: string, erosionRate: number, minConfidence: number, now: string): number;
|
|
25
|
+
/**
|
|
26
|
+
* Compute confidence after applying a contradiction drop.
|
|
27
|
+
*
|
|
28
|
+
* @param currentConfidence - Current confidence (before drop)
|
|
29
|
+
* @param severity - Amount to subtract (e.g. 0.3 for a major contradiction)
|
|
30
|
+
* @param minConfidence - Confidence floor
|
|
31
|
+
*/
|
|
32
|
+
export declare function applyContradiction(currentConfidence: number, severity: number, minConfidence: number): number;
|
|
33
|
+
//# sourceMappingURL=erosion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erosion.d.ts","sourceRoot":"","sources":["../../src/confidence/erosion.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,GACV,MAAM,CAIR;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,iBAAiB,EAAE,MAAM,EACzB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GACpB,MAAM,CAER"}
|