@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.
Files changed (177) hide show
  1. package/dist/__tests__/integration.test.d.ts +8 -0
  2. package/dist/__tests__/integration.test.d.ts.map +1 -0
  3. package/dist/__tests__/integration.test.js +233 -0
  4. package/dist/__tests__/integration.test.js.map +1 -0
  5. package/dist/budget/__tests__/budget.test.d.ts +2 -0
  6. package/dist/budget/__tests__/budget.test.d.ts.map +1 -0
  7. package/dist/budget/__tests__/budget.test.js +238 -0
  8. package/dist/budget/__tests__/budget.test.js.map +1 -0
  9. package/dist/budget/__tests__/token-tracker.test.d.ts +2 -0
  10. package/dist/budget/__tests__/token-tracker.test.d.ts.map +1 -0
  11. package/dist/budget/__tests__/token-tracker.test.js +292 -0
  12. package/dist/budget/__tests__/token-tracker.test.js.map +1 -0
  13. package/dist/budget/index.d.ts +38 -0
  14. package/dist/budget/index.d.ts.map +1 -0
  15. package/dist/budget/index.js +192 -0
  16. package/dist/budget/index.js.map +1 -0
  17. package/dist/budget/token-tracker.d.ts +62 -0
  18. package/dist/budget/token-tracker.d.ts.map +1 -0
  19. package/dist/budget/token-tracker.js +152 -0
  20. package/dist/budget/token-tracker.js.map +1 -0
  21. package/dist/budget/types.d.ts +41 -0
  22. package/dist/budget/types.d.ts.map +1 -0
  23. package/dist/budget/types.js +5 -0
  24. package/dist/budget/types.js.map +1 -0
  25. package/dist/confidence/__tests__/confidence.test.d.ts +2 -0
  26. package/dist/confidence/__tests__/confidence.test.d.ts.map +1 -0
  27. package/dist/confidence/__tests__/confidence.test.js +336 -0
  28. package/dist/confidence/__tests__/confidence.test.js.map +1 -0
  29. package/dist/confidence/erosion.d.ts +33 -0
  30. package/dist/confidence/erosion.d.ts.map +1 -0
  31. package/dist/confidence/erosion.js +42 -0
  32. package/dist/confidence/erosion.js.map +1 -0
  33. package/dist/confidence/index.d.ts +42 -0
  34. package/dist/confidence/index.d.ts.map +1 -0
  35. package/dist/confidence/index.js +168 -0
  36. package/dist/confidence/index.js.map +1 -0
  37. package/dist/confidence/types.d.ts +29 -0
  38. package/dist/confidence/types.d.ts.map +1 -0
  39. package/dist/confidence/types.js +5 -0
  40. package/dist/confidence/types.js.map +1 -0
  41. package/dist/curiosity/__tests__/curiosity.test.d.ts +2 -0
  42. package/dist/curiosity/__tests__/curiosity.test.d.ts.map +1 -0
  43. package/dist/curiosity/__tests__/curiosity.test.js +280 -0
  44. package/dist/curiosity/__tests__/curiosity.test.js.map +1 -0
  45. package/dist/curiosity/dedup.d.ts +29 -0
  46. package/dist/curiosity/dedup.d.ts.map +1 -0
  47. package/dist/curiosity/dedup.js +64 -0
  48. package/dist/curiosity/dedup.js.map +1 -0
  49. package/dist/curiosity/index.d.ts +56 -0
  50. package/dist/curiosity/index.d.ts.map +1 -0
  51. package/dist/curiosity/index.js +163 -0
  52. package/dist/curiosity/index.js.map +1 -0
  53. package/dist/curiosity/types.d.ts +29 -0
  54. package/dist/curiosity/types.d.ts.map +1 -0
  55. package/dist/curiosity/types.js +5 -0
  56. package/dist/curiosity/types.js.map +1 -0
  57. package/dist/index.d.ts +25 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +16 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/index.test.d.ts +2 -0
  62. package/dist/index.test.d.ts.map +1 -0
  63. package/dist/index.test.js +7 -0
  64. package/dist/index.test.js.map +1 -0
  65. package/dist/init.d.ts +17 -0
  66. package/dist/init.d.ts.map +1 -0
  67. package/dist/init.js +153 -0
  68. package/dist/init.js.map +1 -0
  69. package/dist/knowledge-tree/__tests__/knowledge-tree.test.d.ts +2 -0
  70. package/dist/knowledge-tree/__tests__/knowledge-tree.test.d.ts.map +1 -0
  71. package/dist/knowledge-tree/__tests__/knowledge-tree.test.js +317 -0
  72. package/dist/knowledge-tree/__tests__/knowledge-tree.test.js.map +1 -0
  73. package/dist/knowledge-tree/format.d.ts +17 -0
  74. package/dist/knowledge-tree/format.d.ts.map +1 -0
  75. package/dist/knowledge-tree/format.js +48 -0
  76. package/dist/knowledge-tree/format.js.map +1 -0
  77. package/dist/knowledge-tree/index.d.ts +33 -0
  78. package/dist/knowledge-tree/index.d.ts.map +1 -0
  79. package/dist/knowledge-tree/index.js +182 -0
  80. package/dist/knowledge-tree/index.js.map +1 -0
  81. package/dist/knowledge-tree/types.d.ts +37 -0
  82. package/dist/knowledge-tree/types.d.ts.map +1 -0
  83. package/dist/knowledge-tree/types.js +5 -0
  84. package/dist/knowledge-tree/types.js.map +1 -0
  85. package/dist/metadata/__tests__/metadata.test.d.ts +2 -0
  86. package/dist/metadata/__tests__/metadata.test.d.ts.map +1 -0
  87. package/dist/metadata/__tests__/metadata.test.js +196 -0
  88. package/dist/metadata/__tests__/metadata.test.js.map +1 -0
  89. package/dist/metadata/__tests__/search.test.d.ts +2 -0
  90. package/dist/metadata/__tests__/search.test.d.ts.map +1 -0
  91. package/dist/metadata/__tests__/search.test.js +227 -0
  92. package/dist/metadata/__tests__/search.test.js.map +1 -0
  93. package/dist/metadata/index.d.ts +29 -0
  94. package/dist/metadata/index.d.ts.map +1 -0
  95. package/dist/metadata/index.js +108 -0
  96. package/dist/metadata/index.js.map +1 -0
  97. package/dist/metadata/schema.d.ts +8 -0
  98. package/dist/metadata/schema.d.ts.map +1 -0
  99. package/dist/metadata/schema.js +31 -0
  100. package/dist/metadata/schema.js.map +1 -0
  101. package/dist/metadata/search.d.ts +27 -0
  102. package/dist/metadata/search.d.ts.map +1 -0
  103. package/dist/metadata/search.js +57 -0
  104. package/dist/metadata/search.js.map +1 -0
  105. package/dist/metadata/types.d.ts +17 -0
  106. package/dist/metadata/types.d.ts.map +1 -0
  107. package/dist/metadata/types.js +5 -0
  108. package/dist/metadata/types.js.map +1 -0
  109. package/dist/orchestrator/__tests__/orchestrator.test.d.ts +2 -0
  110. package/dist/orchestrator/__tests__/orchestrator.test.d.ts.map +1 -0
  111. package/dist/orchestrator/__tests__/orchestrator.test.js +354 -0
  112. package/dist/orchestrator/__tests__/orchestrator.test.js.map +1 -0
  113. package/dist/orchestrator/index.d.ts +23 -0
  114. package/dist/orchestrator/index.d.ts.map +1 -0
  115. package/dist/orchestrator/index.js +302 -0
  116. package/dist/orchestrator/index.js.map +1 -0
  117. package/dist/orchestrator/scheduler.d.ts +32 -0
  118. package/dist/orchestrator/scheduler.d.ts.map +1 -0
  119. package/dist/orchestrator/scheduler.js +102 -0
  120. package/dist/orchestrator/scheduler.js.map +1 -0
  121. package/dist/orchestrator/types.d.ts +90 -0
  122. package/dist/orchestrator/types.d.ts.map +1 -0
  123. package/dist/orchestrator/types.js +5 -0
  124. package/dist/orchestrator/types.js.map +1 -0
  125. package/dist/pipeline/__tests__/pipeline.test.d.ts +2 -0
  126. package/dist/pipeline/__tests__/pipeline.test.d.ts.map +1 -0
  127. package/dist/pipeline/__tests__/pipeline.test.js +320 -0
  128. package/dist/pipeline/__tests__/pipeline.test.js.map +1 -0
  129. package/dist/pipeline/index.d.ts +23 -0
  130. package/dist/pipeline/index.d.ts.map +1 -0
  131. package/dist/pipeline/index.js +212 -0
  132. package/dist/pipeline/index.js.map +1 -0
  133. package/dist/pipeline/types.d.ts +41 -0
  134. package/dist/pipeline/types.d.ts.map +1 -0
  135. package/dist/pipeline/types.js +5 -0
  136. package/dist/pipeline/types.js.map +1 -0
  137. package/dist/providers/__tests__/providers.test.d.ts +2 -0
  138. package/dist/providers/__tests__/providers.test.d.ts.map +1 -0
  139. package/dist/providers/__tests__/providers.test.js +195 -0
  140. package/dist/providers/__tests__/providers.test.js.map +1 -0
  141. package/dist/providers/claude-model.d.ts +17 -0
  142. package/dist/providers/claude-model.d.ts.map +1 -0
  143. package/dist/providers/claude-model.js +119 -0
  144. package/dist/providers/claude-model.js.map +1 -0
  145. package/dist/providers/index.d.ts +22 -0
  146. package/dist/providers/index.d.ts.map +1 -0
  147. package/dist/providers/index.js +38 -0
  148. package/dist/providers/index.js.map +1 -0
  149. package/dist/providers/openai-search.d.ts +14 -0
  150. package/dist/providers/openai-search.d.ts.map +1 -0
  151. package/dist/providers/openai-search.js +97 -0
  152. package/dist/providers/openai-search.js.map +1 -0
  153. package/dist/providers/types.d.ts +42 -0
  154. package/dist/providers/types.d.ts.map +1 -0
  155. package/dist/providers/types.js +5 -0
  156. package/dist/providers/types.js.map +1 -0
  157. package/dist/types.d.ts +122 -0
  158. package/dist/types.d.ts.map +1 -0
  159. package/dist/types.js +5 -0
  160. package/dist/types.js.map +1 -0
  161. package/dist/vetter/__tests__/vetter.test.d.ts +2 -0
  162. package/dist/vetter/__tests__/vetter.test.d.ts.map +1 -0
  163. package/dist/vetter/__tests__/vetter.test.js +224 -0
  164. package/dist/vetter/__tests__/vetter.test.js.map +1 -0
  165. package/dist/vetter/index.d.ts +23 -0
  166. package/dist/vetter/index.d.ts.map +1 -0
  167. package/dist/vetter/index.js +177 -0
  168. package/dist/vetter/index.js.map +1 -0
  169. package/dist/vetter/resource-tracker.d.ts +49 -0
  170. package/dist/vetter/resource-tracker.d.ts.map +1 -0
  171. package/dist/vetter/resource-tracker.js +183 -0
  172. package/dist/vetter/resource-tracker.js.map +1 -0
  173. package/dist/vetter/types.d.ts +44 -0
  174. package/dist/vetter/types.d.ts.map +1 -0
  175. package/dist/vetter/types.js +5 -0
  176. package/dist/vetter/types.js.map +1 -0
  177. 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,5 @@
1
+ /**
2
+ * Budget tracker type definitions.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/budget/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=confidence.test.d.ts.map
@@ -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"}