@gotza02/sequential-thinking 10000.1.2 → 10000.1.4

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 (32) hide show
  1. package/README.md +39 -249
  2. package/dist/dashboard/server.d.ts +2 -45
  3. package/dist/dashboard/server.js +64 -250
  4. package/dist/index.js +4 -1
  5. package/dist/tools/sports/core/base.d.ts +31 -1
  6. package/dist/tools/sports/core/base.js +25 -0
  7. package/dist/tools/sports/core/cache.d.ts +8 -19
  8. package/dist/tools/sports/core/cache.js +38 -95
  9. package/dist/tools/sports/core/constants.d.ts +4 -63
  10. package/dist/tools/sports/core/constants.js +11 -86
  11. package/dist/tools/sports/core/types.d.ts +146 -34
  12. package/dist/tools/sports/providers/api.d.ts +12 -1
  13. package/dist/tools/sports/providers/api.js +170 -0
  14. package/dist/tools/sports/tools/match.d.ts +5 -0
  15. package/dist/tools/sports/tools/match.js +530 -5
  16. package/package.json +1 -1
  17. package/dist/tools/sports/core/alert-manager.d.ts +0 -96
  18. package/dist/tools/sports/core/alert-manager.js +0 -319
  19. package/dist/tools/sports/core/circuit-breaker.d.ts +0 -40
  20. package/dist/tools/sports/core/circuit-breaker.js +0 -99
  21. package/dist/tools/sports/core/data-quality.d.ts +0 -36
  22. package/dist/tools/sports/core/data-quality.js +0 -243
  23. package/dist/tools/sports/core/historical-analyzer.d.ts +0 -54
  24. package/dist/tools/sports/core/historical-analyzer.js +0 -261
  25. package/dist/tools/sports/core/index.d.ts +0 -13
  26. package/dist/tools/sports/core/index.js +0 -16
  27. package/dist/tools/sports/core/ml-prediction.d.ts +0 -76
  28. package/dist/tools/sports/core/ml-prediction.js +0 -260
  29. package/dist/tools/sports/core/realtime-manager.d.ts +0 -51
  30. package/dist/tools/sports/core/realtime-manager.js +0 -222
  31. package/dist/tools/sports/core/retry.d.ts +0 -29
  32. package/dist/tools/sports/core/retry.js +0 -77
package/dist/index.js CHANGED
@@ -29,7 +29,10 @@ const server = new McpServer({
29
29
  });
30
30
  const thinkingServer = new SequentialThinkingServer(process.env.THOUGHTS_STORAGE_PATH || 'thoughts_history.json', parseInt(process.env.THOUGHT_DELAY_MS || '0', 10));
31
31
  // Start Dashboard
32
- startDashboard(3001);
32
+ const historyPath = process.env.THOUGHTS_STORAGE_PATH || 'thoughts_history.json';
33
+ startDashboard(3001, historyPath).catch(err => {
34
+ console.error("[Dashboard] Failed to start:", err);
35
+ });
33
36
  const knowledgeGraph = new ProjectKnowledgeGraph();
34
37
  const memoryGraph = new KnowledgeGraphManager(process.env.MEMORY_GRAPH_PATH || 'knowledge_graph.json');
35
38
  const notesManager = new NotesManager(process.env.NOTES_STORAGE_PATH || 'project_notes.json');
@@ -2,7 +2,7 @@
2
2
  * SPORTS MODULE BASE CLASSES
3
3
  * Abstract base classes and interfaces for data providers
4
4
  */
5
- import { Match, Team, Player, TableEntry, APIResponse, ProviderStatus, ProviderType } from './types.js';
5
+ import { Match, Team, Player, TableEntry, APIResponse, ProviderStatus, ProviderType, HeadToHead, MatchOdds } from './types.js';
6
6
  import { CacheService } from './cache.js';
7
7
  /**
8
8
  * Base interface for all data providers
@@ -48,6 +48,18 @@ export interface IDataProvider {
48
48
  * Search for players
49
49
  */
50
50
  searchPlayers(query: string): Promise<APIResponse<Player[]>>;
51
+ /**
52
+ * Fetch head-to-head statistics between two teams
53
+ */
54
+ getH2H(matchId: string, team1Id?: string, team2Id?: string): Promise<APIResponse<HeadToHead>>;
55
+ /**
56
+ * Fetch recent form (last N matches) for a team
57
+ */
58
+ getTeamForm(teamId: string, last?: number): Promise<APIResponse<Match[]>>;
59
+ /**
60
+ * Fetch odds for a match
61
+ */
62
+ getMatchOdds(matchId: string): Promise<APIResponse<MatchOdds>>;
51
63
  }
52
64
  /**
53
65
  * Abstract base class for API-based providers
@@ -84,6 +96,18 @@ export declare abstract class APIProviderBase implements IDataProvider {
84
96
  abstract getPlayer(playerId: string): Promise<APIResponse<Player>>;
85
97
  abstract searchTeams(query: string): Promise<APIResponse<Team[]>>;
86
98
  abstract searchPlayers(query: string): Promise<APIResponse<Player[]>>;
99
+ /**
100
+ * Head-to-head statistics (optional, may not be supported by all providers)
101
+ */
102
+ abstract getH2H(matchId: string, team1Id?: string, team2Id?: string): Promise<APIResponse<HeadToHead>>;
103
+ /**
104
+ * Team recent form (optional, may not be supported by all providers)
105
+ */
106
+ abstract getTeamForm(teamId: string, last?: number): Promise<APIResponse<Match[]>>;
107
+ /**
108
+ * Match odds (optional, may not be supported by all providers)
109
+ */
110
+ abstract getMatchOdds(matchId: string): Promise<APIResponse<MatchOdds>>;
87
111
  /**
88
112
  * Make a rate-limited API call
89
113
  */
@@ -117,6 +141,9 @@ export declare abstract class ScraperProviderBase implements IDataProvider {
117
141
  abstract getPlayer(playerId: string): Promise<APIResponse<Player>>;
118
142
  abstract searchTeams(query: string): Promise<APIResponse<Team[]>>;
119
143
  abstract searchPlayers(query: string): Promise<APIResponse<Player[]>>;
144
+ getH2H(matchId: string, team1Id?: string, team2Id?: string): Promise<APIResponse<HeadToHead>>;
145
+ getTeamForm(teamId: string, last?: number): Promise<APIResponse<Match[]>>;
146
+ getMatchOdds(matchId: string): Promise<APIResponse<MatchOdds>>;
120
147
  /**
121
148
  * Scrape a webpage and extract structured data
122
149
  */
@@ -143,6 +170,9 @@ export declare class FallbackProvider implements IDataProvider {
143
170
  getPlayer(playerId: string): Promise<APIResponse<Player>>;
144
171
  searchTeams(query: string): Promise<APIResponse<Team[]>>;
145
172
  searchPlayers(query: string): Promise<APIResponse<Player[]>>;
173
+ getH2H(matchId: string, team1Id?: string, team2Id?: string): Promise<APIResponse<HeadToHead>>;
174
+ getTeamForm(teamId: string, last?: number): Promise<APIResponse<Match[]>>;
175
+ getMatchOdds(matchId: string): Promise<APIResponse<MatchOdds>>;
146
176
  }
147
177
  /**
148
178
  * Base class for sports tools
@@ -141,6 +141,16 @@ export class ScraperProviderBase {
141
141
  quotaLimit: Infinity,
142
142
  };
143
143
  }
144
+ // Optional methods - may not be implemented by all scrapers
145
+ async getH2H(matchId, team1Id, team2Id) {
146
+ return { success: false, error: 'H2H not available via scraper' };
147
+ }
148
+ async getTeamForm(teamId, last) {
149
+ return { success: false, error: 'Team form not available via scraper' };
150
+ }
151
+ async getMatchOdds(matchId) {
152
+ return { success: false, error: 'Match odds not available via scraper' };
153
+ }
144
154
  /**
145
155
  * Scrape a webpage and extract structured data
146
156
  */
@@ -243,6 +253,21 @@ export class FallbackProvider {
243
253
  return this.cache.getOrSet(cacheKey, () => this.tryProviders(p => p.searchPlayers(query)), 60 * 60 * 1000 // 1 hour
244
254
  );
245
255
  }
256
+ async getH2H(matchId, team1Id, team2Id) {
257
+ const cacheKey = CacheService.generateKey('h2h', matchId);
258
+ return this.cache.getOrSet(cacheKey, () => this.tryProviders(p => p.getH2H(matchId, team1Id, team2Id)), 30 * 60 * 1000 // 30 minutes
259
+ );
260
+ }
261
+ async getTeamForm(teamId, last) {
262
+ const cacheKey = CacheService.generateKey('form', teamId, last?.toString() || '5');
263
+ return this.cache.getOrSet(cacheKey, () => this.tryProviders(p => p.getTeamForm(teamId, last)), 30 * 60 * 1000 // 30 minutes
264
+ );
265
+ }
266
+ async getMatchOdds(matchId) {
267
+ const cacheKey = CacheService.generateKey('odds', matchId);
268
+ return this.cache.getOrSet(cacheKey, () => this.tryProviders(p => p.getMatchOdds(matchId)), 5 * 60 * 1000 // 5 minutes (odds change frequently)
269
+ );
270
+ }
246
271
  }
247
272
  /**
248
273
  * Base class for sports tools
@@ -1,19 +1,18 @@
1
1
  /**
2
- * ENHANCED CACHE SERVICE
3
- * TTL-based caching with stale-while-revalidate pattern
2
+ * SPORTS MODULE CACHE SERVICE
3
+ * TTL-based caching with file persistence for the football intelligence system
4
4
  */
5
5
  /**
6
- * CacheService - Thread-safe TTL-based caching with stale-while-revalidate
6
+ * CacheService - Thread-safe TTL-based caching with persistence
7
7
  */
8
8
  export declare class CacheService {
9
9
  private cache;
10
10
  private cachePath;
11
11
  private maxAge;
12
- private staleAge;
13
12
  private maxSize;
14
13
  private savePending;
15
14
  private saveTimer;
16
- constructor(cachePath?: string, maxAge?: number, maxSize?: number, staleAge?: number);
15
+ constructor(cachePath?: string, maxAge?: number, maxSize?: number);
17
16
  /**
18
17
  * Generate a cache key from components
19
18
  */
@@ -25,16 +24,7 @@ export declare class CacheService {
25
24
  /**
26
25
  * Set a value in cache
27
26
  */
28
- set<T>(key: string, data: T, ttl?: number, staleTtl?: number): void;
29
- /**
30
- * Get or set with stale-while-revalidate pattern
31
- * Returns cached value immediately, refreshes in background if stale
32
- */
33
- getOrSetWithStaleRevalidate<T>(key: string, factory: () => T | Promise<T>, ttl?: number, staleTtl?: number): Promise<T>;
34
- /**
35
- * Refresh data in background
36
- */
37
- private refreshInBackground;
27
+ set<T>(key: string, data: T, ttl?: number): void;
38
28
  /**
39
29
  * Check if a key exists and is not expired
40
30
  */
@@ -59,7 +49,6 @@ export declare class CacheService {
59
49
  hits: number;
60
50
  age: number;
61
51
  ttl: number;
62
- isStale: boolean;
63
52
  }>;
64
53
  };
65
54
  /**
@@ -67,7 +56,7 @@ export declare class CacheService {
67
56
  */
68
57
  cleanup(): number;
69
58
  /**
70
- * Evict the oldest entry (LRU with hit weighting)
59
+ * Evict the oldest entry (LRU)
71
60
  */
72
61
  private evictOldest;
73
62
  /**
@@ -89,7 +78,7 @@ export declare class CacheService {
89
78
  /**
90
79
  * Get or set pattern - returns cached value or computes and caches it
91
80
  */
92
- getOrSet<T>(key: string, factory: () => T | Promise<T>, ttl?: number, staleTtl?: number): Promise<T>;
81
+ getOrSet<T>(key: string, factory: () => T | Promise<T>, ttl?: number): Promise<T>;
93
82
  /**
94
83
  * Get multiple keys at once
95
84
  */
@@ -97,7 +86,7 @@ export declare class CacheService {
97
86
  /**
98
87
  * Set multiple keys at once
99
88
  */
100
- setMultiple<T>(entries: Map<string, T>, ttl?: number, staleTtl?: number): void;
89
+ setMultiple<T>(entries: Map<string, T>, ttl?: number): void;
101
90
  /**
102
91
  * Invalidate cache by pattern
103
92
  */
@@ -1,26 +1,24 @@
1
1
  /**
2
- * ENHANCED CACHE SERVICE
3
- * TTL-based caching with stale-while-revalidate pattern
2
+ * SPORTS MODULE CACHE SERVICE
3
+ * TTL-based caching with file persistence for the football intelligence system
4
4
  */
5
5
  import * as fs from 'fs/promises';
6
6
  import * as path from 'path';
7
7
  import { CACHE_CONFIG } from './constants.js';
8
8
  import { logger, createSafeRegex } from '../../../utils.js';
9
9
  /**
10
- * CacheService - Thread-safe TTL-based caching with stale-while-revalidate
10
+ * CacheService - Thread-safe TTL-based caching with persistence
11
11
  */
12
12
  export class CacheService {
13
13
  cache = new Map();
14
14
  cachePath;
15
15
  maxAge;
16
- staleAge;
17
16
  maxSize;
18
17
  savePending = false;
19
18
  saveTimer = null;
20
- constructor(cachePath = CACHE_CONFIG.CACHE_PATH, maxAge = CACHE_CONFIG.DEFAULT_TTL, maxSize = CACHE_CONFIG.MAX_SIZE, staleAge) {
19
+ constructor(cachePath = CACHE_CONFIG.CACHE_PATH, maxAge = CACHE_CONFIG.DEFAULT_TTL, maxSize = CACHE_CONFIG.MAX_SIZE) {
21
20
  this.cachePath = path.resolve(cachePath);
22
21
  this.maxAge = maxAge;
23
- this.staleAge = staleAge || maxAge * 2;
24
22
  this.maxSize = maxSize;
25
23
  this.loadFromFile();
26
24
  }
@@ -38,12 +36,11 @@ export class CacheService {
38
36
  if (!entry) {
39
37
  return null;
40
38
  }
41
- // Check if expired (including stale period)
39
+ // Check if expired
42
40
  const now = Date.now();
43
- const totalTtl = entry.ttl + entry.staleTtl;
44
- if (now - entry.timestamp > totalTtl) {
41
+ if (now - entry.timestamp > entry.ttl) {
45
42
  this.cache.delete(key);
46
- logger.debug(`Cache expired (including stale): ${key}`);
43
+ logger.debug(`Cache expired: ${key}`);
47
44
  return null;
48
45
  }
49
46
  // Increment hit counter
@@ -54,7 +51,7 @@ export class CacheService {
54
51
  /**
55
52
  * Set a value in cache
56
53
  */
57
- set(key, data, ttl, staleTtl) {
54
+ set(key, data, ttl) {
58
55
  const now = Date.now();
59
56
  // Check if we need to evict old entries
60
57
  if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
@@ -65,64 +62,11 @@ export class CacheService {
65
62
  data,
66
63
  timestamp: now,
67
64
  ttl: ttl || this.maxAge,
68
- staleTtl: staleTtl || this.staleAge,
69
65
  hits: 0,
70
66
  });
71
- logger.debug(`Cache set: ${key} (TTL: ${ttl || this.maxAge}ms, Stale: ${staleTtl || this.staleAge}ms)`);
67
+ logger.debug(`Cache set: ${key} (TTL: ${ttl || this.maxAge}ms)`);
72
68
  this.scheduleSave();
73
69
  }
74
- /**
75
- * Get or set with stale-while-revalidate pattern
76
- * Returns cached value immediately, refreshes in background if stale
77
- */
78
- async getOrSetWithStaleRevalidate(key, factory, ttl, staleTtl) {
79
- const entry = this.cache.get(key);
80
- const now = Date.now();
81
- const effectiveTtl = ttl || this.maxAge;
82
- const effectiveStaleTtl = staleTtl || this.staleAge;
83
- if (entry) {
84
- const age = now - entry.timestamp;
85
- // Data is fresh - use it
86
- if (age < effectiveTtl) {
87
- entry.hits++;
88
- return entry.data;
89
- }
90
- // Data is stale but within stale TTL - use it and refresh in background
91
- if (age < effectiveTtl + effectiveStaleTtl) {
92
- entry.hits++;
93
- if (!entry.isRefreshing) {
94
- this.refreshInBackground(key, factory, effectiveTtl, effectiveStaleTtl);
95
- }
96
- return entry.data;
97
- }
98
- }
99
- // No data or expired beyond stale TTL - fetch new data
100
- const value = await factory();
101
- this.set(key, value, effectiveTtl, effectiveStaleTtl);
102
- return value;
103
- }
104
- /**
105
- * Refresh data in background
106
- */
107
- async refreshInBackground(key, factory, ttl, staleTtl) {
108
- const entry = this.cache.get(key);
109
- if (entry) {
110
- entry.isRefreshing = true;
111
- }
112
- try {
113
- const value = await factory();
114
- this.set(key, value, ttl, staleTtl);
115
- logger.debug(`Background refresh successful: ${key}`);
116
- }
117
- catch (error) {
118
- logger.error(`Background refresh failed for ${key}: ${error}`);
119
- }
120
- finally {
121
- if (entry) {
122
- entry.isRefreshing = false;
123
- }
124
- }
125
- }
126
70
  /**
127
71
  * Check if a key exists and is not expired
128
72
  */
@@ -131,8 +75,7 @@ export class CacheService {
131
75
  if (!entry)
132
76
  return false;
133
77
  const now = Date.now();
134
- const totalTtl = entry.ttl + entry.staleTtl;
135
- if (now - entry.timestamp > totalTtl) {
78
+ if (now - entry.timestamp > entry.ttl) {
136
79
  this.cache.delete(key);
137
80
  return false;
138
81
  }
@@ -157,16 +100,12 @@ export class CacheService {
157
100
  */
158
101
  getStats() {
159
102
  const now = Date.now();
160
- const entries = Array.from(this.cache.values()).map(entry => {
161
- const age = now - entry.timestamp;
162
- return {
163
- key: entry.key,
164
- hits: entry.hits,
165
- age,
166
- ttl: entry.ttl,
167
- isStale: age > entry.ttl,
168
- };
169
- });
103
+ const entries = Array.from(this.cache.values()).map(entry => ({
104
+ key: entry.key,
105
+ hits: entry.hits,
106
+ age: now - entry.timestamp,
107
+ ttl: entry.ttl,
108
+ }));
170
109
  return {
171
110
  size: this.cache.size,
172
111
  maxSize: this.maxSize,
@@ -181,8 +120,7 @@ export class CacheService {
181
120
  const now = Date.now();
182
121
  let removed = 0;
183
122
  for (const [key, entry] of this.cache.entries()) {
184
- const totalTtl = entry.ttl + entry.staleTtl;
185
- if (now - entry.timestamp > totalTtl) {
123
+ if (now - entry.timestamp > entry.ttl) {
186
124
  this.cache.delete(key);
187
125
  removed++;
188
126
  }
@@ -194,22 +132,20 @@ export class CacheService {
194
132
  return removed;
195
133
  }
196
134
  /**
197
- * Evict the oldest entry (LRU with hit weighting)
135
+ * Evict the oldest entry (LRU)
198
136
  */
199
137
  evictOldest() {
200
138
  let oldestKey = null;
201
- let lowestScore = Infinity;
202
- // Evict based on age weighted by hits
139
+ let oldestTime = Infinity;
203
140
  for (const [key, entry] of this.cache.entries()) {
204
- const score = (Date.now() - entry.timestamp) / (entry.hits + 1);
205
- if (score < lowestScore) {
206
- lowestScore = score;
141
+ if (entry.timestamp < oldestTime) {
142
+ oldestTime = entry.timestamp;
207
143
  oldestKey = key;
208
144
  }
209
145
  }
210
146
  if (oldestKey) {
211
147
  this.cache.delete(oldestKey);
212
- logger.debug(`Evicted LRU entry: ${oldestKey}`);
148
+ logger.debug(`Evicted oldest cache entry: ${oldestKey}`);
213
149
  }
214
150
  }
215
151
  /**
@@ -222,7 +158,7 @@ export class CacheService {
222
158
  this.saveTimer = setTimeout(() => {
223
159
  this.saveToFile();
224
160
  this.saveTimer = null;
225
- }, 1000);
161
+ }, 1000); // Save after 1 second of inactivity
226
162
  }
227
163
  /**
228
164
  * Save cache to file
@@ -256,8 +192,7 @@ export class CacheService {
256
192
  const now = Date.now();
257
193
  let restored = 0;
258
194
  for (const [key, entry] of entries) {
259
- const totalTtl = entry.ttl + entry.staleTtl;
260
- if (now - entry.timestamp < totalTtl) {
195
+ if (now - entry.timestamp < entry.ttl) {
261
196
  this.cache.set(key, entry);
262
197
  restored++;
263
198
  }
@@ -265,6 +200,7 @@ export class CacheService {
265
200
  logger.info(`Cache loaded: ${restored}/${entries.length} entries restored`);
266
201
  }
267
202
  catch (error) {
203
+ // File doesn't exist or is invalid - start fresh
268
204
  logger.debug('No existing cache file found, starting fresh');
269
205
  }
270
206
  }
@@ -281,8 +217,14 @@ export class CacheService {
281
217
  /**
282
218
  * Get or set pattern - returns cached value or computes and caches it
283
219
  */
284
- async getOrSet(key, factory, ttl, staleTtl) {
285
- return this.getOrSetWithStaleRevalidate(key, factory, ttl, staleTtl);
220
+ async getOrSet(key, factory, ttl) {
221
+ const cached = this.get(key);
222
+ if (cached !== null) {
223
+ return cached;
224
+ }
225
+ const value = await factory();
226
+ this.set(key, value, ttl);
227
+ return value;
286
228
  }
287
229
  /**
288
230
  * Get multiple keys at once
@@ -300,15 +242,16 @@ export class CacheService {
300
242
  /**
301
243
  * Set multiple keys at once
302
244
  */
303
- setMultiple(entries, ttl, staleTtl) {
245
+ setMultiple(entries, ttl) {
304
246
  for (const [key, value] of entries.entries()) {
305
- this.set(key, value, ttl, staleTtl);
247
+ this.set(key, value, ttl);
306
248
  }
307
249
  }
308
250
  /**
309
251
  * Invalidate cache by pattern
310
252
  */
311
253
  invalidatePattern(pattern) {
254
+ // Use safe regex creation to prevent ReDoS attacks
312
255
  const regex = createSafeRegex(pattern);
313
256
  let removed = 0;
314
257
  for (const key of this.cache.keys()) {
@@ -345,10 +288,10 @@ let globalCache = null;
345
288
  export function getGlobalCache() {
346
289
  if (!globalCache) {
347
290
  globalCache = new CacheService();
348
- // Cleanup expired entries every 2 minutes
291
+ // Cleanup expired entries every 5 minutes
349
292
  setInterval(() => {
350
293
  globalCache?.cleanup();
351
- }, 2 * 60 * 1000);
294
+ }, 5 * 60 * 1000);
352
295
  }
353
296
  return globalCache;
354
297
  }
@@ -10,40 +10,25 @@ export declare const API_CONFIG: {
10
10
  readonly FOOTBALL_DATA_BASE: "https://api.football-data.org/v4";
11
11
  readonly SPORTS_DB_KEY: string;
12
12
  readonly SPORTS_DB_BASE: "https://www.thesportsdb.com/api/v1/json";
13
- readonly ODDS_API_KEY: string;
14
- readonly ODDS_API_BASE: "https://api.the-odds-api.com/v4";
15
- readonly SPORTRADAR_KEY: string;
16
- readonly SPORTRADAR_BASE: "https://api.sportradar.us/soccer/trial/v4";
17
13
  readonly RATE_LIMITS: {
18
14
  readonly API_FOOTBALL: 10;
19
15
  readonly FOOTBALL_DATA: 10;
20
16
  readonly SPORTS_DB: 30;
21
- readonly ODDS_API: 20;
22
- readonly SPORTRADAR: 100;
23
17
  };
24
18
  };
25
19
  export declare const CACHE_CONFIG: {
26
20
  readonly DEFAULT_TTL: number;
27
21
  readonly TTL: {
28
22
  readonly LIVE_SCORES: number;
29
- readonly LIVE_EVENTS: number;
30
- readonly ODDS: number;
31
23
  readonly MATCH_DETAILS: number;
32
24
  readonly STANDINGS: number;
33
25
  readonly TEAM_STATS: number;
34
26
  readonly PLAYER_STATS: number;
27
+ readonly ODDS: number;
35
28
  readonly TRANSFER_NEWS: number;
36
- readonly PREDICTIONS: number;
37
- };
38
- readonly STALE_MULTIPLIERS: {
39
- readonly LIVE_SCORES: 2;
40
- readonly ODDS: 2;
41
- readonly MATCH_DETAILS: 2;
42
- readonly STANDINGS: 1.5;
43
- readonly TEAM_STATS: 1.5;
44
29
  };
45
30
  readonly CACHE_PATH: string;
46
- readonly MAX_SIZE: 2000;
31
+ readonly MAX_SIZE: 1000;
47
32
  };
48
33
  export declare const SCRAPER_CONFIG: {
49
34
  readonly PRIORITY_DOMAINS: readonly ["understat.com", "bbc.co.uk/sport", "sportsmole.co.uk", "skysports.com", "goal.com", "thesquareball.net", "fbref.com", "whoscored.com", "sofascore.com", "flashscore.com"];
@@ -187,53 +172,9 @@ export declare const ERRORS: {
187
172
  readonly TIMEOUT: "Request timed out.";
188
173
  readonly INVALID_RESPONSE: "Invalid response from API.";
189
174
  readonly ALL_PROVIDERS_FAILED: "All data providers failed.";
190
- readonly CIRCUIT_BREAKER_OPEN: "Service temporarily unavailable due to repeated failures.";
191
- };
192
- export declare const ALERT_CONFIG: {
193
- readonly CHECK_INTERVAL: 10000;
194
- readonly DEFAULT_COOLDOWN: 300000;
195
- readonly MAX_ALERTS_PER_HOUR: 10;
196
- readonly TYPES: {
197
- readonly ODDS_DROP: "odds_drop";
198
- readonly ODDS_VALUE: "odds_value";
199
- readonly GOAL: "goal";
200
- readonly RED_CARD: "red_card";
201
- readonly LINEUP_CHANGE: "lineup_change";
202
- readonly MATCH_START: "match_start";
203
- readonly MATCH_END: "match_end";
204
- readonly CUSTOM: "custom";
205
- };
206
- };
207
- export declare const REALTIME_CONFIG: {
208
- readonly WS_RECONNECT_INTERVAL: 5000;
209
- readonly WS_MAX_RECONNECT_ATTEMPTS: 10;
210
- readonly POLLING_INTERVALS: {
211
- readonly LIVE_SCORES: 15000;
212
- readonly ODDS: 30000;
213
- readonly MATCH_EVENTS: 5000;
214
- };
215
- readonly EVENT_BATCH_SIZE: 10;
216
- readonly EVENT_BATCH_TIMEOUT: 1000;
217
- };
218
- export declare const ML_CONFIG: {
219
- readonly MIN_TRAINING_MATCHES: 50;
220
- readonly FEATURE_WEIGHTS: {
221
- readonly form: 0.25;
222
- readonly h2h: 0.2;
223
- readonly home_advantage: 0.15;
224
- readonly xg: 0.15;
225
- readonly injuries: 0.1;
226
- readonly fatigue: 0.1;
227
- readonly weather: 0.05;
228
- };
229
- readonly CONFIDENCE_THRESHOLDS: {
230
- readonly high: 0.7;
231
- readonly medium: 0.55;
232
- readonly low: 0.4;
233
- };
234
175
  };
235
176
  export declare const MODULE_INFO: {
236
177
  readonly NAME: "sports-module";
237
- readonly VERSION: "3.0.0";
238
- readonly DESCRIPTION: "Football Intelligence System for MCP Server - Realtime Edition";
178
+ readonly VERSION: "2.0.0";
179
+ readonly DESCRIPTION: "Football Intelligence System for MCP Server";
239
180
  };