@gotza02/sequential-thinking 10000.1.2 → 10000.1.3

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/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');
@@ -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
  };
@@ -14,49 +14,31 @@ export const API_CONFIG = {
14
14
  // TheSportsDB
15
15
  SPORTS_DB_KEY: process.env.SPORTS_DB_KEY || '',
16
16
  SPORTS_DB_BASE: 'https://www.thesportsdb.com/api/v1/json',
17
- // Odds API
18
- ODDS_API_KEY: process.env.ODDS_API_KEY || '',
19
- ODDS_API_BASE: 'https://api.the-odds-api.com/v4',
20
- // SportRadar (requires enterprise license)
21
- SPORTRADAR_KEY: process.env.SPORTRADAR_KEY || '',
22
- SPORTRADAR_BASE: 'https://api.sportradar.us/soccer/trial/v4',
23
17
  // Rate limits (requests per minute)
24
18
  RATE_LIMITS: {
25
19
  API_FOOTBALL: 10,
26
20
  FOOTBALL_DATA: 10,
27
21
  SPORTS_DB: 30,
28
- ODDS_API: 20,
29
- SPORTRADAR: 100,
30
22
  }
31
23
  };
32
24
  // ============= Cache Configuration =============
33
25
  export const CACHE_CONFIG = {
34
26
  // Default TTL in milliseconds
35
27
  DEFAULT_TTL: parseInt(process.env.SPORTS_CACHE_TTL || '300000'), // 5 minutes
36
- // Specific TTLs for different data types (OPTIMIZED FOR REALTIME)
28
+ // Specific TTLs for different data types
37
29
  TTL: {
38
- LIVE_SCORES: 15 * 1000, // 15 seconds (was 1 minute)
39
- LIVE_EVENTS: 5 * 1000, // 5 seconds for live match events
40
- ODDS: 30 * 1000, // 30 seconds (was 2 minutes)
41
- MATCH_DETAILS: 2 * 60 * 1000, // 2 minutes (was 5 minutes)
42
- STANDINGS: 15 * 60 * 1000, // 15 minutes (was 30 minutes)
43
- TEAM_STATS: 30 * 60 * 1000, // 30 minutes (was 1 hour)
44
- PLAYER_STATS: 30 * 60 * 1000, // 30 minutes (was 1 hour)
45
- TRANSFER_NEWS: 10 * 60 * 1000, // 10 minutes (was 15 minutes)
46
- PREDICTIONS: 60 * 60 * 1000, // 1 hour
47
- },
48
- // Stale-while-revalidate multipliers
49
- STALE_MULTIPLIERS: {
50
- LIVE_SCORES: 2, // Stale for 30 seconds (15s * 2)
51
- ODDS: 2, // Stale for 1 minute (30s * 2)
52
- MATCH_DETAILS: 2, // Stale for 4 minutes
53
- STANDINGS: 1.5, // Stale for 22.5 minutes
54
- TEAM_STATS: 1.5, // Stale for 45 minutes
30
+ LIVE_SCORES: 60 * 1000, // 1 minute
31
+ MATCH_DETAILS: 5 * 60 * 1000, // 5 minutes
32
+ STANDINGS: 30 * 60 * 1000, // 30 minutes
33
+ TEAM_STATS: 60 * 60 * 1000, // 1 hour
34
+ PLAYER_STATS: 60 * 60 * 1000, // 1 hour
35
+ ODDS: 2 * 60 * 1000, // 2 minutes
36
+ TRANSFER_NEWS: 15 * 60 * 1000, // 15 minutes
55
37
  },
56
38
  // Cache file path
57
39
  CACHE_PATH: process.env.SPORTS_CACHE_PATH || '.sports_cache.json',
58
40
  // Max cache size (number of entries)
59
- MAX_SIZE: 2000,
41
+ MAX_SIZE: 1000,
60
42
  };
61
43
  // ============= Scraping Configuration =============
62
44
  export const SCRAPER_CONFIG = {
@@ -170,67 +152,10 @@ export const ERRORS = {
170
152
  TIMEOUT: 'Request timed out.',
171
153
  INVALID_RESPONSE: 'Invalid response from API.',
172
154
  ALL_PROVIDERS_FAILED: 'All data providers failed.',
173
- CIRCUIT_BREAKER_OPEN: 'Service temporarily unavailable due to repeated failures.',
174
- };
175
- // ============= Alert Configuration =============
176
- export const ALERT_CONFIG = {
177
- // Check interval for alerts (milliseconds)
178
- CHECK_INTERVAL: 10000, // 10 seconds
179
- // Default cooldown between same alert (milliseconds)
180
- DEFAULT_COOLDOWN: 300000, // 5 minutes
181
- // Max alerts per hour per rule
182
- MAX_ALERTS_PER_HOUR: 10,
183
- // Alert types
184
- TYPES: {
185
- ODDS_DROP: 'odds_drop',
186
- ODDS_VALUE: 'odds_value',
187
- GOAL: 'goal',
188
- RED_CARD: 'red_card',
189
- LINEUP_CHANGE: 'lineup_change',
190
- MATCH_START: 'match_start',
191
- MATCH_END: 'match_end',
192
- CUSTOM: 'custom',
193
- },
194
- };
195
- // ============= Realtime Configuration =============
196
- export const REALTIME_CONFIG = {
197
- // WebSocket reconnection
198
- WS_RECONNECT_INTERVAL: 5000,
199
- WS_MAX_RECONNECT_ATTEMPTS: 10,
200
- // Polling intervals (fallback when WebSocket unavailable)
201
- POLLING_INTERVALS: {
202
- LIVE_SCORES: 15000, // 15 seconds
203
- ODDS: 30000, // 30 seconds
204
- MATCH_EVENTS: 5000, // 5 seconds
205
- },
206
- // Event batching
207
- EVENT_BATCH_SIZE: 10,
208
- EVENT_BATCH_TIMEOUT: 1000,
209
- };
210
- // ============= ML Prediction Configuration =============
211
- export const ML_CONFIG = {
212
- // Minimum matches for training
213
- MIN_TRAINING_MATCHES: 50,
214
- // Feature weights
215
- FEATURE_WEIGHTS: {
216
- form: 0.25,
217
- h2h: 0.20,
218
- home_advantage: 0.15,
219
- xg: 0.15,
220
- injuries: 0.10,
221
- fatigue: 0.10,
222
- weather: 0.05,
223
- },
224
- // Confidence thresholds
225
- CONFIDENCE_THRESHOLDS: {
226
- high: 0.70,
227
- medium: 0.55,
228
- low: 0.40,
229
- },
230
155
  };
231
156
  // ============= Version Info =============
232
157
  export const MODULE_INFO = {
233
158
  NAME: 'sports-module',
234
- VERSION: '3.0.0',
235
- DESCRIPTION: 'Football Intelligence System for MCP Server - Realtime Edition',
159
+ VERSION: '2.0.0',
160
+ DESCRIPTION: 'Football Intelligence System for MCP Server',
236
161
  };
@@ -7,7 +7,7 @@ export type MatchStatus = 'scheduled' | 'live' | 'finished' | 'postponed' | 'can
7
7
  export type BetType = 'home' | 'draw' | 'away' | 'over' | 'under' | 'btts' | 'handicap';
8
8
  export type KellyVariant = 'full' | 'half' | 'quarter';
9
9
  export type QueryType = 'general' | 'h2h' | 'form' | 'news' | 'stats' | 'odds' | 'referee' | 'weather' | 'fatigue' | 'setpieces';
10
- export type ProviderType = 'api-football' | 'football-data' | 'sports-db' | 'odds-api' | 'sportradar' | 'scraper';
10
+ export type ProviderType = 'api-football' | 'football-data' | 'sports-db' | 'scraper';
11
11
  export interface SearchQuery {
12
12
  type: QueryType;
13
13
  query: string;
@@ -175,8 +175,6 @@ export interface Match {
175
175
  homeSubstitutes?: Player[];
176
176
  awaySubstitutes?: Player[];
177
177
  events?: MatchEvent[];
178
- dataQuality?: number;
179
- lastUpdated?: Date;
180
178
  }
181
179
  export interface MatchOdds {
182
180
  homeWin: number;
@@ -346,7 +344,6 @@ export interface APIResponse<T = any> {
346
344
  provider?: ProviderType;
347
345
  cached?: boolean;
348
346
  rateLimited?: boolean;
349
- quality?: number;
350
347
  }
351
348
  export interface ProviderStatus {
352
349
  name: ProviderType;
@@ -355,7 +352,6 @@ export interface ProviderStatus {
355
352
  quotaLimit: number;
356
353
  rateLimitUntil?: Date;
357
354
  lastCall?: Date;
358
- circuitBreakerState?: 'closed' | 'open' | 'half-open';
359
355
  }
360
356
  export interface ComparisonResult {
361
357
  teamA: Team;
@@ -381,38 +377,3 @@ export interface LiveScoreUpdate {
381
377
  events: MatchEvent[];
382
378
  timestamp: Date;
383
379
  }
384
- export interface MLPrediction {
385
- matchId: string;
386
- homeWinProbability: number;
387
- drawProbability: number;
388
- awayWinProbability: number;
389
- over25Probability?: number;
390
- bttsProbability?: number;
391
- confidence: number;
392
- factors: PredictionFactor[];
393
- timestamp: Date;
394
- }
395
- export interface PredictionFactor {
396
- name: string;
397
- weight: number;
398
- impact: 'positive' | 'negative' | 'neutral';
399
- description: string;
400
- }
401
- export interface HistoricalPattern {
402
- pattern: string;
403
- occurrence: number;
404
- successRate: number;
405
- avgOdds: number;
406
- profit: number;
407
- }
408
- export interface TeamHistoricalPerformance {
409
- team: Team;
410
- totalMatches: number;
411
- wins: number;
412
- draws: number;
413
- losses: number;
414
- avgGoalsFor: number;
415
- avgGoalsAgainst: number;
416
- homeAdvantage: number;
417
- patterns: HistoricalPattern[];
418
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gotza02/sequential-thinking",
3
- "version": "10000.1.2",
3
+ "version": "10000.1.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },