verifiable-thinking-mcp 0.4.0
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/LICENSE +21 -0
- package/README.md +339 -0
- package/package.json +75 -0
- package/src/index.ts +38 -0
- package/src/lib/cache.ts +246 -0
- package/src/lib/compression.ts +804 -0
- package/src/lib/compute/cache.ts +86 -0
- package/src/lib/compute/classifier.ts +555 -0
- package/src/lib/compute/confidence.ts +79 -0
- package/src/lib/compute/context.ts +154 -0
- package/src/lib/compute/extract.ts +200 -0
- package/src/lib/compute/filter.ts +224 -0
- package/src/lib/compute/index.ts +171 -0
- package/src/lib/compute/math.ts +247 -0
- package/src/lib/compute/patterns.ts +564 -0
- package/src/lib/compute/registry.ts +145 -0
- package/src/lib/compute/solvers/arithmetic.ts +65 -0
- package/src/lib/compute/solvers/calculus.ts +249 -0
- package/src/lib/compute/solvers/derivation-core.ts +371 -0
- package/src/lib/compute/solvers/derivation-latex.ts +160 -0
- package/src/lib/compute/solvers/derivation-mistakes.ts +1046 -0
- package/src/lib/compute/solvers/derivation-simplify.ts +451 -0
- package/src/lib/compute/solvers/derivation-transform.ts +620 -0
- package/src/lib/compute/solvers/derivation.ts +67 -0
- package/src/lib/compute/solvers/facts.ts +120 -0
- package/src/lib/compute/solvers/formula.ts +728 -0
- package/src/lib/compute/solvers/index.ts +36 -0
- package/src/lib/compute/solvers/logic.ts +422 -0
- package/src/lib/compute/solvers/probability.ts +307 -0
- package/src/lib/compute/solvers/statistics.ts +262 -0
- package/src/lib/compute/solvers/word-problems.ts +408 -0
- package/src/lib/compute/types.ts +107 -0
- package/src/lib/concepts.ts +111 -0
- package/src/lib/domain.ts +731 -0
- package/src/lib/extraction.ts +912 -0
- package/src/lib/index.ts +122 -0
- package/src/lib/judge.ts +260 -0
- package/src/lib/math/ast.ts +842 -0
- package/src/lib/math/index.ts +8 -0
- package/src/lib/math/operators.ts +171 -0
- package/src/lib/math/tokenizer.ts +477 -0
- package/src/lib/patterns.ts +200 -0
- package/src/lib/session.ts +825 -0
- package/src/lib/think/challenge.ts +323 -0
- package/src/lib/think/complexity.ts +504 -0
- package/src/lib/think/confidence-drift.ts +507 -0
- package/src/lib/think/consistency.ts +347 -0
- package/src/lib/think/guidance.ts +188 -0
- package/src/lib/think/helpers.ts +568 -0
- package/src/lib/think/hypothesis.ts +216 -0
- package/src/lib/think/index.ts +127 -0
- package/src/lib/think/prompts.ts +262 -0
- package/src/lib/think/route.ts +358 -0
- package/src/lib/think/schema.ts +98 -0
- package/src/lib/think/scratchpad-schema.ts +662 -0
- package/src/lib/think/spot-check.ts +961 -0
- package/src/lib/think/types.ts +93 -0
- package/src/lib/think/verification.ts +260 -0
- package/src/lib/tokens.ts +177 -0
- package/src/lib/verification.ts +620 -0
- package/src/prompts/index.ts +10 -0
- package/src/prompts/templates.ts +336 -0
- package/src/resources/index.ts +8 -0
- package/src/resources/sessions.ts +196 -0
- package/src/tools/compress.ts +138 -0
- package/src/tools/index.ts +5 -0
- package/src/tools/scratchpad.ts +2659 -0
- package/src/tools/sessions.ts +144 -0
package/src/lib/cache.ts
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verification Cache - Content-hash based caching for verification results
|
|
3
|
+
* Skips re-verification of identical thoughts across sessions
|
|
4
|
+
* Includes rate limiting to prevent memory exhaustion under high load
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { VerificationDomain, VerificationResult } from "./verification.ts";
|
|
8
|
+
|
|
9
|
+
interface CacheEntry {
|
|
10
|
+
result: VerificationResult;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
hits: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface RateLimitWindow {
|
|
16
|
+
count: number;
|
|
17
|
+
window_start: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface CacheConfig {
|
|
21
|
+
max_entries: number;
|
|
22
|
+
ttl_ms: number;
|
|
23
|
+
// Rate limiting
|
|
24
|
+
rate_limit_ops: number; // Max operations per window
|
|
25
|
+
rate_limit_window_ms: number; // Window size in ms
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const DEFAULT_CONFIG: CacheConfig = {
|
|
29
|
+
max_entries: 1000,
|
|
30
|
+
ttl_ms: 60 * 60 * 1000, // 1 hour
|
|
31
|
+
rate_limit_ops: 100, // 100 ops per second
|
|
32
|
+
rate_limit_window_ms: 1000, // 1 second window
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export interface CacheStats {
|
|
36
|
+
size: number;
|
|
37
|
+
max: number;
|
|
38
|
+
hit_rate: number;
|
|
39
|
+
hits: number;
|
|
40
|
+
misses: number;
|
|
41
|
+
rate_limited: number;
|
|
42
|
+
ops_in_window: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
class VerificationCacheImpl {
|
|
46
|
+
private cache: Map<string, CacheEntry> = new Map();
|
|
47
|
+
private config: CacheConfig;
|
|
48
|
+
|
|
49
|
+
// Rate limiting state
|
|
50
|
+
private rateLimit: RateLimitWindow = { count: 0, window_start: Date.now() };
|
|
51
|
+
private rateLimitedCount = 0;
|
|
52
|
+
|
|
53
|
+
// Stats
|
|
54
|
+
private totalHits = 0;
|
|
55
|
+
private totalMisses = 0;
|
|
56
|
+
|
|
57
|
+
constructor(config: Partial<CacheConfig> = {}) {
|
|
58
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Check and update rate limit. Returns true if operation is allowed.
|
|
63
|
+
*/
|
|
64
|
+
private checkRateLimit(): boolean {
|
|
65
|
+
const now = Date.now();
|
|
66
|
+
|
|
67
|
+
// Reset window if expired
|
|
68
|
+
if (now - this.rateLimit.window_start >= this.config.rate_limit_window_ms) {
|
|
69
|
+
this.rateLimit = { count: 0, window_start: now };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Check if under limit
|
|
73
|
+
if (this.rateLimit.count >= this.config.rate_limit_ops) {
|
|
74
|
+
this.rateLimitedCount++;
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.rateLimit.count++;
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Generate cache key from thought content, domain, and context hash
|
|
84
|
+
*/
|
|
85
|
+
private generateKey(thought: string, domain: VerificationDomain, context: string[]): string {
|
|
86
|
+
const contextHash = this.hashString(context.join("|"));
|
|
87
|
+
const thoughtHash = this.hashString(thought);
|
|
88
|
+
return `${domain}:${thoughtHash}:${contextHash}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Simple string hash (djb2 algorithm)
|
|
93
|
+
*/
|
|
94
|
+
private hashString(str: string): string {
|
|
95
|
+
let hash = 5381;
|
|
96
|
+
for (let i = 0; i < str.length; i++) {
|
|
97
|
+
hash = (hash << 5) + hash + str.charCodeAt(i);
|
|
98
|
+
hash = hash & hash; // Convert to 32-bit integer
|
|
99
|
+
}
|
|
100
|
+
return Math.abs(hash).toString(36);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Get cached verification result if exists and not expired
|
|
105
|
+
* Returns null if rate limited or cache miss
|
|
106
|
+
*/
|
|
107
|
+
get(thought: string, domain: VerificationDomain, context: string[]): VerificationResult | null {
|
|
108
|
+
// Rate limit check
|
|
109
|
+
if (!this.checkRateLimit()) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const key = this.generateKey(thought, domain, context);
|
|
114
|
+
const entry = this.cache.get(key);
|
|
115
|
+
|
|
116
|
+
if (!entry) {
|
|
117
|
+
this.totalMisses++;
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Check TTL
|
|
122
|
+
if (Date.now() - entry.timestamp > this.config.ttl_ms) {
|
|
123
|
+
this.cache.delete(key);
|
|
124
|
+
this.totalMisses++;
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Update hit count
|
|
129
|
+
entry.hits++;
|
|
130
|
+
this.totalHits++;
|
|
131
|
+
return entry.result;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Store verification result in cache
|
|
136
|
+
* Respects rate limiting - silently drops if rate limited
|
|
137
|
+
*/
|
|
138
|
+
set(
|
|
139
|
+
thought: string,
|
|
140
|
+
domain: VerificationDomain,
|
|
141
|
+
context: string[],
|
|
142
|
+
result: VerificationResult,
|
|
143
|
+
): boolean {
|
|
144
|
+
// Rate limit check
|
|
145
|
+
if (!this.checkRateLimit()) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Evict oldest entries if at capacity
|
|
150
|
+
if (this.cache.size >= this.config.max_entries) {
|
|
151
|
+
this.evictOldest();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const key = this.generateKey(thought, domain, context);
|
|
155
|
+
this.cache.set(key, {
|
|
156
|
+
result,
|
|
157
|
+
timestamp: Date.now(),
|
|
158
|
+
hits: 0,
|
|
159
|
+
});
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Evict oldest/least-hit entries
|
|
165
|
+
*/
|
|
166
|
+
private evictOldest(): void {
|
|
167
|
+
// Remove entries that are expired first
|
|
168
|
+
const now = Date.now();
|
|
169
|
+
for (const [key, entry] of this.cache) {
|
|
170
|
+
if (now - entry.timestamp > this.config.ttl_ms) {
|
|
171
|
+
this.cache.delete(key);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// If still over limit, remove lowest hit count entries
|
|
176
|
+
if (this.cache.size >= this.config.max_entries) {
|
|
177
|
+
const entries = Array.from(this.cache.entries()).sort((a, b) => a[1].hits - b[1].hits);
|
|
178
|
+
|
|
179
|
+
const toRemove = Math.ceil(this.config.max_entries * 0.1); // Remove 10%
|
|
180
|
+
for (let i = 0; i < toRemove && i < entries.length; i++) {
|
|
181
|
+
const entry = entries[i];
|
|
182
|
+
if (entry) this.cache.delete(entry[0]);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Get cache statistics including rate limiting info
|
|
189
|
+
*/
|
|
190
|
+
getStats(): CacheStats {
|
|
191
|
+
let _entryHits = 0;
|
|
192
|
+
for (const entry of this.cache.values()) {
|
|
193
|
+
_entryHits += entry.hits;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
size: this.cache.size,
|
|
198
|
+
max: this.config.max_entries,
|
|
199
|
+
hit_rate:
|
|
200
|
+
this.totalHits + this.totalMisses > 0
|
|
201
|
+
? this.totalHits / (this.totalHits + this.totalMisses)
|
|
202
|
+
: 0,
|
|
203
|
+
hits: this.totalHits,
|
|
204
|
+
misses: this.totalMisses,
|
|
205
|
+
rate_limited: this.rateLimitedCount,
|
|
206
|
+
ops_in_window: this.rateLimit.count,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Check if currently rate limited
|
|
212
|
+
*/
|
|
213
|
+
isRateLimited(): boolean {
|
|
214
|
+
const now = Date.now();
|
|
215
|
+
if (now - this.rateLimit.window_start >= this.config.rate_limit_window_ms) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
return this.rateLimit.count >= this.config.rate_limit_ops;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Clear all cached entries and reset stats
|
|
223
|
+
*/
|
|
224
|
+
clear(): number {
|
|
225
|
+
const count = this.cache.size;
|
|
226
|
+
this.cache.clear();
|
|
227
|
+
this.totalHits = 0;
|
|
228
|
+
this.totalMisses = 0;
|
|
229
|
+
this.rateLimitedCount = 0;
|
|
230
|
+
this.rateLimit = { count: 0, window_start: Date.now() };
|
|
231
|
+
return count;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Update configuration (useful for testing)
|
|
236
|
+
*/
|
|
237
|
+
configure(config: Partial<CacheConfig>): void {
|
|
238
|
+
this.config = { ...this.config, ...config };
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Singleton instance
|
|
243
|
+
export const verificationCache = new VerificationCacheImpl();
|
|
244
|
+
|
|
245
|
+
// Export class for testing with custom config
|
|
246
|
+
export { VerificationCacheImpl as VerificationCache };
|