gthinking 1.3.0 → 2.1.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 (271) hide show
  1. package/.eslintrc.js +34 -0
  2. package/ANALYSIS_SUMMARY.md +363 -0
  3. package/README.md +230 -250
  4. package/dist/analysis/analysis-engine.d.ts +63 -0
  5. package/dist/analysis/analysis-engine.d.ts.map +1 -0
  6. package/dist/analysis/analysis-engine.js +322 -0
  7. package/dist/analysis/analysis-engine.js.map +1 -0
  8. package/dist/core/config.d.ts +1419 -0
  9. package/dist/core/config.d.ts.map +1 -0
  10. package/dist/core/config.js +361 -0
  11. package/dist/core/config.js.map +1 -0
  12. package/dist/core/engine.d.ts +176 -0
  13. package/dist/core/engine.d.ts.map +1 -0
  14. package/dist/core/engine.js +604 -0
  15. package/dist/core/engine.js.map +1 -0
  16. package/dist/core/errors.d.ts +153 -0
  17. package/dist/core/errors.d.ts.map +1 -0
  18. package/dist/core/errors.js +287 -0
  19. package/dist/core/errors.js.map +1 -0
  20. package/dist/core/index.d.ts +7 -0
  21. package/dist/core/index.d.ts.map +1 -0
  22. package/dist/{types.js → core/index.js} +8 -4
  23. package/dist/core/index.js.map +1 -0
  24. package/dist/core/pipeline.d.ts +121 -0
  25. package/dist/core/pipeline.d.ts.map +1 -0
  26. package/dist/core/pipeline.js +289 -0
  27. package/dist/core/pipeline.js.map +1 -0
  28. package/dist/core/rate-limiter.d.ts +58 -0
  29. package/dist/core/rate-limiter.d.ts.map +1 -0
  30. package/dist/core/rate-limiter.js +133 -0
  31. package/dist/core/rate-limiter.js.map +1 -0
  32. package/dist/core/session-manager.d.ts +96 -0
  33. package/dist/core/session-manager.d.ts.map +1 -0
  34. package/dist/core/session-manager.js +223 -0
  35. package/dist/core/session-manager.js.map +1 -0
  36. package/dist/creativity/creativity-engine.d.ts +6 -0
  37. package/dist/creativity/creativity-engine.d.ts.map +1 -0
  38. package/dist/creativity/creativity-engine.js +17 -0
  39. package/dist/creativity/creativity-engine.js.map +1 -0
  40. package/dist/index.d.ts +24 -32
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +130 -104
  43. package/dist/index.js.map +1 -1
  44. package/dist/learning/learning-engine.d.ts +6 -0
  45. package/dist/learning/learning-engine.d.ts.map +1 -0
  46. package/dist/learning/learning-engine.js +17 -0
  47. package/dist/learning/learning-engine.js.map +1 -0
  48. package/dist/llm/index.d.ts +10 -0
  49. package/dist/llm/index.d.ts.map +1 -0
  50. package/dist/llm/index.js +26 -0
  51. package/dist/llm/index.js.map +1 -0
  52. package/dist/llm/llm-service.d.ts +109 -0
  53. package/dist/llm/llm-service.d.ts.map +1 -0
  54. package/dist/llm/llm-service.js +224 -0
  55. package/dist/llm/llm-service.js.map +1 -0
  56. package/dist/llm/providers/base.d.ts +85 -0
  57. package/dist/llm/providers/base.d.ts.map +1 -0
  58. package/dist/llm/providers/base.js +57 -0
  59. package/dist/llm/providers/base.js.map +1 -0
  60. package/dist/llm/providers/cli.d.ts +23 -0
  61. package/dist/llm/providers/cli.d.ts.map +1 -0
  62. package/dist/llm/providers/cli.js +158 -0
  63. package/dist/llm/providers/cli.js.map +1 -0
  64. package/dist/llm/providers/gemini.d.ts +30 -0
  65. package/dist/llm/providers/gemini.d.ts.map +1 -0
  66. package/dist/llm/providers/gemini.js +168 -0
  67. package/dist/llm/providers/gemini.js.map +1 -0
  68. package/dist/llm/sanitization.d.ts +50 -0
  69. package/dist/llm/sanitization.d.ts.map +1 -0
  70. package/dist/llm/sanitization.js +149 -0
  71. package/dist/llm/sanitization.js.map +1 -0
  72. package/dist/{server.d.ts.map → mcp/server.d.ts.map} +1 -1
  73. package/dist/mcp/server.js +108 -0
  74. package/dist/mcp/server.js.map +1 -0
  75. package/dist/planning/planning-engine.d.ts +6 -0
  76. package/dist/planning/planning-engine.d.ts.map +1 -0
  77. package/dist/planning/planning-engine.js +17 -0
  78. package/dist/planning/planning-engine.js.map +1 -0
  79. package/dist/reasoning/reasoning-engine.d.ts +6 -0
  80. package/dist/reasoning/reasoning-engine.d.ts.map +1 -0
  81. package/dist/reasoning/reasoning-engine.js +17 -0
  82. package/dist/reasoning/reasoning-engine.js.map +1 -0
  83. package/dist/search/search-engine.d.ts +99 -0
  84. package/dist/search/search-engine.d.ts.map +1 -0
  85. package/dist/search/search-engine.js +271 -0
  86. package/dist/search/search-engine.js.map +1 -0
  87. package/dist/synthesis/synthesis-engine.d.ts +6 -0
  88. package/dist/synthesis/synthesis-engine.d.ts.map +1 -0
  89. package/dist/synthesis/synthesis-engine.js +17 -0
  90. package/dist/synthesis/synthesis-engine.js.map +1 -0
  91. package/dist/types/analysis.d.ts +1534 -49
  92. package/dist/types/analysis.d.ts.map +1 -1
  93. package/dist/types/analysis.js +250 -0
  94. package/dist/types/analysis.js.map +1 -1
  95. package/dist/types/core.d.ts +257 -30
  96. package/dist/types/core.d.ts.map +1 -1
  97. package/dist/types/core.js +148 -18
  98. package/dist/types/core.js.map +1 -1
  99. package/dist/types/creativity.d.ts +2871 -56
  100. package/dist/types/creativity.d.ts.map +1 -1
  101. package/dist/types/creativity.js +195 -0
  102. package/dist/types/creativity.js.map +1 -1
  103. package/dist/types/index.d.ts +6 -2
  104. package/dist/types/index.d.ts.map +1 -1
  105. package/dist/types/index.js +17 -2
  106. package/dist/types/index.js.map +1 -1
  107. package/dist/types/learning.d.ts +851 -61
  108. package/dist/types/learning.d.ts.map +1 -1
  109. package/dist/types/learning.js +155 -0
  110. package/dist/types/learning.js.map +1 -1
  111. package/dist/types/planning.d.ts +2223 -71
  112. package/dist/types/planning.d.ts.map +1 -1
  113. package/dist/types/planning.js +190 -0
  114. package/dist/types/planning.js.map +1 -1
  115. package/dist/types/reasoning.d.ts +2209 -72
  116. package/dist/types/reasoning.d.ts.map +1 -1
  117. package/dist/types/reasoning.js +200 -1
  118. package/dist/types/reasoning.js.map +1 -1
  119. package/dist/types/search.d.ts +981 -53
  120. package/dist/types/search.d.ts.map +1 -1
  121. package/dist/types/search.js +137 -0
  122. package/dist/types/search.js.map +1 -1
  123. package/dist/types/synthesis.d.ts +583 -38
  124. package/dist/types/synthesis.d.ts.map +1 -1
  125. package/dist/types/synthesis.js +138 -0
  126. package/dist/types/synthesis.js.map +1 -1
  127. package/dist/utils/cache.d.ts +144 -0
  128. package/dist/utils/cache.d.ts.map +1 -0
  129. package/dist/utils/cache.js +288 -0
  130. package/dist/utils/cache.js.map +1 -0
  131. package/dist/utils/id-generator.d.ts +89 -0
  132. package/dist/utils/id-generator.d.ts.map +1 -0
  133. package/dist/utils/id-generator.js +132 -0
  134. package/dist/utils/id-generator.js.map +1 -0
  135. package/dist/utils/index.d.ts +11 -0
  136. package/dist/utils/index.d.ts.map +1 -0
  137. package/dist/utils/index.js +33 -0
  138. package/dist/utils/index.js.map +1 -0
  139. package/dist/utils/logger.d.ts +142 -0
  140. package/dist/utils/logger.d.ts.map +1 -0
  141. package/dist/utils/logger.js +248 -0
  142. package/dist/utils/logger.js.map +1 -0
  143. package/dist/utils/metrics.d.ts +149 -0
  144. package/dist/utils/metrics.d.ts.map +1 -0
  145. package/dist/utils/metrics.js +296 -0
  146. package/dist/utils/metrics.js.map +1 -0
  147. package/dist/utils/timer.d.ts +7 -0
  148. package/dist/utils/timer.d.ts.map +1 -0
  149. package/dist/utils/timer.js +17 -0
  150. package/dist/utils/timer.js.map +1 -0
  151. package/dist/utils/validation.d.ts +147 -0
  152. package/dist/utils/validation.d.ts.map +1 -0
  153. package/dist/utils/validation.js +275 -0
  154. package/dist/utils/validation.js.map +1 -0
  155. package/docs/API.md +411 -0
  156. package/docs/ARCHITECTURE.md +271 -0
  157. package/docs/CHANGELOG.md +283 -0
  158. package/jest.config.js +28 -0
  159. package/package.json +43 -30
  160. package/src/analysis/analysis-engine.ts +383 -0
  161. package/src/core/config.ts +406 -0
  162. package/src/core/engine.ts +785 -0
  163. package/src/core/errors.ts +349 -0
  164. package/src/core/index.ts +12 -0
  165. package/src/core/pipeline.ts +424 -0
  166. package/src/core/rate-limiter.ts +155 -0
  167. package/src/core/session-manager.ts +269 -0
  168. package/src/creativity/creativity-engine.ts +14 -0
  169. package/src/index.ts +178 -0
  170. package/src/learning/learning-engine.ts +14 -0
  171. package/src/llm/index.ts +10 -0
  172. package/src/llm/llm-service.ts +285 -0
  173. package/src/llm/providers/base.ts +146 -0
  174. package/src/llm/providers/cli.ts +186 -0
  175. package/src/llm/providers/gemini.ts +201 -0
  176. package/src/llm/sanitization.ts +178 -0
  177. package/src/mcp/server.ts +117 -0
  178. package/src/planning/planning-engine.ts +14 -0
  179. package/src/reasoning/reasoning-engine.ts +14 -0
  180. package/src/search/search-engine.ts +333 -0
  181. package/src/synthesis/synthesis-engine.ts +14 -0
  182. package/src/types/analysis.ts +337 -0
  183. package/src/types/core.ts +342 -0
  184. package/src/types/creativity.ts +268 -0
  185. package/src/types/index.ts +31 -0
  186. package/src/types/learning.ts +215 -0
  187. package/src/types/planning.ts +251 -0
  188. package/src/types/reasoning.ts +288 -0
  189. package/src/types/search.ts +192 -0
  190. package/src/types/synthesis.ts +187 -0
  191. package/src/utils/cache.ts +363 -0
  192. package/src/utils/id-generator.ts +135 -0
  193. package/src/utils/index.ts +22 -0
  194. package/src/utils/logger.ts +290 -0
  195. package/src/utils/metrics.ts +380 -0
  196. package/src/utils/timer.ts +15 -0
  197. package/src/utils/validation.ts +297 -0
  198. package/tests/setup.ts +22 -0
  199. package/tests/unit/cache.test.ts +189 -0
  200. package/tests/unit/engine.test.ts +179 -0
  201. package/tests/unit/validation.test.ts +218 -0
  202. package/tsconfig.json +17 -12
  203. package/GEMINI.md +0 -68
  204. package/analysis.ts +0 -1063
  205. package/creativity.ts +0 -1055
  206. package/dist/analysis.d.ts +0 -54
  207. package/dist/analysis.d.ts.map +0 -1
  208. package/dist/analysis.js +0 -866
  209. package/dist/analysis.js.map +0 -1
  210. package/dist/creativity.d.ts +0 -81
  211. package/dist/creativity.d.ts.map +0 -1
  212. package/dist/creativity.js +0 -828
  213. package/dist/creativity.js.map +0 -1
  214. package/dist/engine.d.ts +0 -90
  215. package/dist/engine.d.ts.map +0 -1
  216. package/dist/engine.js +0 -720
  217. package/dist/engine.js.map +0 -1
  218. package/dist/examples.d.ts +0 -7
  219. package/dist/examples.d.ts.map +0 -1
  220. package/dist/examples.js +0 -506
  221. package/dist/examples.js.map +0 -1
  222. package/dist/learning.d.ts +0 -72
  223. package/dist/learning.d.ts.map +0 -1
  224. package/dist/learning.js +0 -615
  225. package/dist/learning.js.map +0 -1
  226. package/dist/llm-service.d.ts +0 -21
  227. package/dist/llm-service.d.ts.map +0 -1
  228. package/dist/llm-service.js +0 -100
  229. package/dist/llm-service.js.map +0 -1
  230. package/dist/planning.d.ts +0 -62
  231. package/dist/planning.d.ts.map +0 -1
  232. package/dist/planning.js +0 -886
  233. package/dist/planning.js.map +0 -1
  234. package/dist/reasoning.d.ts +0 -73
  235. package/dist/reasoning.d.ts.map +0 -1
  236. package/dist/reasoning.js +0 -845
  237. package/dist/reasoning.js.map +0 -1
  238. package/dist/search-discovery.d.ts +0 -73
  239. package/dist/search-discovery.d.ts.map +0 -1
  240. package/dist/search-discovery.js +0 -548
  241. package/dist/search-discovery.js.map +0 -1
  242. package/dist/server.js +0 -113
  243. package/dist/server.js.map +0 -1
  244. package/dist/types/engine.d.ts +0 -55
  245. package/dist/types/engine.d.ts.map +0 -1
  246. package/dist/types/engine.js +0 -3
  247. package/dist/types/engine.js.map +0 -1
  248. package/dist/types.d.ts +0 -6
  249. package/dist/types.d.ts.map +0 -1
  250. package/dist/types.js.map +0 -1
  251. package/engine.ts +0 -1009
  252. package/examples.ts +0 -717
  253. package/index.ts +0 -106
  254. package/learning.ts +0 -779
  255. package/llm-service.ts +0 -120
  256. package/planning.ts +0 -1101
  257. package/reasoning.ts +0 -1079
  258. package/search-discovery.ts +0 -700
  259. package/server.ts +0 -115
  260. package/types/analysis.ts +0 -69
  261. package/types/core.ts +0 -90
  262. package/types/creativity.ts +0 -72
  263. package/types/engine.ts +0 -60
  264. package/types/index.ts +0 -9
  265. package/types/learning.ts +0 -69
  266. package/types/planning.ts +0 -85
  267. package/types/reasoning.ts +0 -92
  268. package/types/search.ts +0 -58
  269. package/types/synthesis.ts +0 -43
  270. package/types.ts +0 -6
  271. /package/dist/{server.d.ts → mcp/server.d.ts} +0 -0
package/learning.ts DELETED
@@ -1,779 +0,0 @@
1
- /**
2
- * Learning Module
3
- * Context memory, pattern recognition, feedback integration, and knowledge base management
4
- */
5
-
6
- import {
7
- LearningContext,
8
- Interaction,
9
- Feedback,
10
- Pattern,
11
- KnowledgeGraph,
12
- KnowledgeNode,
13
- KnowledgeEdge,
14
- UserPreferences,
15
- ThinkingEvent,
16
- ThinkingError,
17
- ThinkingStage,
18
- SearchResult
19
- } from './types';
20
- import { EventEmitter } from 'events';
21
-
22
- // ============================================================================
23
- // PATTERN RECOGNITION ENGINE
24
- // ============================================================================
25
-
26
- class PatternRecognitionEngine {
27
- private patterns: Map<string, Pattern> = new Map();
28
-
29
- recognize(input: string, context: string): Pattern[] {
30
- const matchedPatterns: Pattern[] = [];
31
-
32
- this.patterns.forEach(pattern => {
33
- const matchScore = this.calculateMatchScore(input, pattern.pattern);
34
- if (matchScore > 0.7) {
35
- matchedPatterns.push({
36
- ...pattern,
37
- frequency: pattern.frequency + 1,
38
- lastObserved: new Date()
39
- });
40
- }
41
- });
42
-
43
- // Also extract new patterns from input
44
- const newPatterns = this.extractPatterns(input, context);
45
- newPatterns.forEach(p => {
46
- if (!this.patterns.has(p.id)) {
47
- this.patterns.set(p.id, p);
48
- matchedPatterns.push(p);
49
- }
50
- });
51
-
52
- return matchedPatterns.sort((a, b) => b.successRate - a.successRate);
53
- }
54
-
55
- updatePatternSuccess(patternId: string, success: boolean): void {
56
- const pattern = this.patterns.get(patternId);
57
- if (pattern) {
58
- // Update success rate using exponential moving average
59
- const alpha = 0.3;
60
- pattern.successRate = alpha * (success ? 1 : 0) + (1 - alpha) * pattern.successRate;
61
- pattern.lastObserved = new Date();
62
- }
63
- }
64
-
65
- private calculateMatchScore(input: string, pattern: string): number {
66
- const inputWords = input.toLowerCase().split(/\s+/);
67
- const patternWords = pattern.toLowerCase().split(/\s+/);
68
-
69
- const matches = patternWords.filter(pw =>
70
- inputWords.some(iw => iw.includes(pw) || pw.includes(iw))
71
- ).length;
72
-
73
- return matches / Math.max(patternWords.length, 1);
74
- }
75
-
76
- private extractPatterns(input: string, context: string): Pattern[] {
77
- const patterns: Pattern[] = [];
78
-
79
- // Extract query patterns
80
- const queryPattern = this.extractQueryPattern(input);
81
- if (queryPattern) {
82
- patterns.push(queryPattern);
83
- }
84
-
85
- // Extract context patterns
86
- const contextPattern = this.extractContextPattern(context);
87
- if (contextPattern) {
88
- patterns.push(contextPattern);
89
- }
90
-
91
- return patterns;
92
- }
93
-
94
- private extractQueryPattern(input: string): Pattern | null {
95
- // Extract key terms that form a pattern
96
- const keyTerms = input
97
- .toLowerCase()
98
- .split(/\s+/)
99
- .filter(w => w.length > 4 && !this.isStopWord(w));
100
-
101
- if (keyTerms.length < 2) return null;
102
-
103
- return {
104
- id: `pattern_query_${keyTerms.join('_')}`,
105
- type: 'query_pattern',
106
- pattern: keyTerms.join(' '),
107
- frequency: 1,
108
- successRate: 0.5,
109
- lastObserved: new Date()
110
- };
111
- }
112
-
113
- private extractContextPattern(context: string): Pattern | null {
114
- const topics = this.extractTopics(context);
115
- if (topics.length < 2) return null;
116
-
117
- return {
118
- id: `pattern_context_${topics.join('_')}`,
119
- type: 'response_pattern',
120
- pattern: topics.join(' '),
121
- frequency: 1,
122
- successRate: 0.5,
123
- lastObserved: new Date()
124
- };
125
- }
126
-
127
- private isStopWord(word: string): boolean {
128
- const stopWords = new Set(['what', 'how', 'when', 'where', 'why', 'who', 'which', 'this', 'that', 'these', 'those']);
129
- return stopWords.has(word.toLowerCase());
130
- }
131
-
132
- private extractTopics(text: string): string[] {
133
- return text
134
- .toLowerCase()
135
- .match(/\b\w{5,}\b/g)
136
- ?.filter((w, i, arr) => arr.indexOf(w) === i)
137
- ?.slice(0, 5) || [];
138
- }
139
-
140
- getPatternsByType(type: Pattern['type']): Pattern[] {
141
- return Array.from(this.patterns.values()).filter(p => p.type === type);
142
- }
143
-
144
- getTopPatterns(limit: number = 10): Pattern[] {
145
- return Array.from(this.patterns.values())
146
- .sort((a, b) => b.successRate * b.frequency - a.successRate * a.frequency)
147
- .slice(0, limit);
148
- }
149
- }
150
-
151
- // ============================================================================
152
- // KNOWLEDGE GRAPH MANAGER
153
- // ============================================================================
154
-
155
- class KnowledgeGraphManager {
156
- private graph: KnowledgeGraph;
157
-
158
- constructor() {
159
- this.graph = {
160
- nodes: [],
161
- edges: [],
162
- version: 1,
163
- lastUpdated: new Date()
164
- };
165
- }
166
-
167
- addNode(node: Omit<KnowledgeNode, 'id'>): KnowledgeNode {
168
- const newNode: KnowledgeNode = {
169
- ...node,
170
- id: `node_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`
171
- };
172
-
173
- // Check for similar existing nodes
174
- const existingNode = this.findSimilarNode(newNode);
175
- if (existingNode) {
176
- // Merge with existing node
177
- this.mergeNodes(existingNode, newNode);
178
- return existingNode;
179
- }
180
-
181
- this.graph.nodes.push(newNode);
182
- this.updateGraph();
183
- return newNode;
184
- }
185
-
186
- addEdge(from: string, to: string, relation: string, strength: number, evidence: string[]): void {
187
- // Check if edge already exists
188
- const existingEdge = this.graph.edges.find(e =>
189
- e.from === from && e.to === to && e.relation === relation
190
- );
191
-
192
- if (existingEdge) {
193
- // Update existing edge strength
194
- existingEdge.strength = Math.min(1, existingEdge.strength + strength * 0.1);
195
- existingEdge.evidence = [...new Set([...existingEdge.evidence, ...evidence])];
196
- } else {
197
- this.graph.edges.push({
198
- from,
199
- to,
200
- relation,
201
- strength,
202
- evidence
203
- });
204
- }
205
-
206
- this.updateGraph();
207
- }
208
-
209
- findRelated(nodeId: string, maxDepth: number = 2): KnowledgeNode[] {
210
- const related = new Set<string>();
211
- const visited = new Set<string>();
212
-
213
- const traverse = (currentId: string, depth: number) => {
214
- if (depth > maxDepth || visited.has(currentId)) return;
215
- visited.add(currentId);
216
-
217
- this.graph.edges
218
- .filter(e => e.from === currentId || e.to === currentId)
219
- .forEach(e => {
220
- const relatedId = e.from === currentId ? e.to : e.from;
221
- related.add(relatedId);
222
- traverse(relatedId, depth + 1);
223
- });
224
- };
225
-
226
- traverse(nodeId, 0);
227
- return this.graph.nodes.filter(n => related.has(n.id));
228
- }
229
-
230
- query(query: string): KnowledgeNode[] {
231
- const queryWords = query.toLowerCase().split(/\s+/);
232
-
233
- return this.graph.nodes
234
- .map(node => ({
235
- node,
236
- score: this.calculateRelevance(node, queryWords)
237
- }))
238
- .filter(({ score }) => score > 0.3)
239
- .sort((a, b) => b.score - a.score)
240
- .map(({ node }) => node);
241
- }
242
-
243
- infer(fromNodeId: string, relationType?: string): KnowledgeNode[] {
244
- const edges = this.graph.edges.filter(e =>
245
- e.from === fromNodeId &&
246
- (relationType ? e.relation === relationType : true) &&
247
- e.strength > 0.5
248
- );
249
-
250
- return edges.map(e => this.graph.nodes.find(n => n.id === e.to)).filter(Boolean) as KnowledgeNode[];
251
- }
252
-
253
- private findSimilarNode(node: KnowledgeNode): KnowledgeNode | undefined {
254
- return this.graph.nodes.find(n => {
255
- const labelSimilarity = this.calculateSimilarity(n.label, node.label);
256
- return labelSimilarity > 0.8;
257
- });
258
- }
259
-
260
- private mergeNodes(existing: KnowledgeNode, newNode: KnowledgeNode): void {
261
- // Merge properties
262
- existing.properties = { ...existing.properties, ...newNode.properties };
263
-
264
- // Update confidence
265
- existing.confidence = Math.max(existing.confidence, newNode.confidence);
266
-
267
- // Merge sources
268
- existing.sources = [...new Set([...existing.sources, ...newNode.sources])];
269
- }
270
-
271
- private calculateRelevance(node: KnowledgeNode, queryWords: string[]): number {
272
- const nodeText = `${node.label} ${JSON.stringify(node.properties)}`.toLowerCase();
273
- const matches = queryWords.filter(qw => nodeText.includes(qw)).length;
274
- return matches / queryWords.length * node.confidence;
275
- }
276
-
277
- private calculateSimilarity(str1: string, str2: string): number {
278
- const words1 = str1.toLowerCase().split(/\s+/);
279
- const words2 = str2.toLowerCase().split(/\s+/);
280
-
281
- const intersection = words1.filter(w => words2.includes(w));
282
- const union = [...new Set([...words1, ...words2])];
283
-
284
- return intersection.length / union.length;
285
- }
286
-
287
- private updateGraph(): void {
288
- this.graph.version++;
289
- this.graph.lastUpdated = new Date();
290
- }
291
-
292
- getGraph(): KnowledgeGraph {
293
- return { ...this.graph };
294
- }
295
-
296
- exportGraph(): string {
297
- return JSON.stringify(this.graph, null, 2);
298
- }
299
-
300
- importGraph(json: string): void {
301
- this.graph = JSON.parse(json);
302
- }
303
- }
304
-
305
- // ============================================================================
306
- // PREFERENCE LEARNING ENGINE
307
- // ============================================================================
308
-
309
- class PreferenceLearningEngine {
310
- private preferences: Map<string, UserPreferences> = new Map();
311
- private defaultPreferences: UserPreferences = {
312
- responseStyle: 'detailed',
313
- preferredSources: [],
314
- topicInterests: [],
315
- excludedTopics: [],
316
- language: 'en'
317
- };
318
-
319
- getPreferences(userId?: string): UserPreferences {
320
- if (userId && this.preferences.has(userId)) {
321
- return this.preferences.get(userId)!;
322
- }
323
- return { ...this.defaultPreferences };
324
- }
325
-
326
- updatePreferences(userId: string, updates: Partial<UserPreferences>): void {
327
- const current = this.getPreferences(userId);
328
- this.preferences.set(userId, { ...current, ...updates });
329
- }
330
-
331
- learnFromInteraction(userId: string, interaction: Interaction): void {
332
- const prefs = this.getPreferences(userId);
333
-
334
- // Learn from query patterns
335
- const queryTopics = this.extractTopics(interaction.query);
336
- prefs.topicInterests = [...new Set([...prefs.topicInterests, ...queryTopics])];
337
-
338
- // Learn from feedback
339
- if (interaction.feedback) {
340
- this.learnFromFeedback(userId, interaction.feedback);
341
- }
342
-
343
- // Infer response style preference
344
- if (interaction.response.length < 100) {
345
- prefs.responseStyle = 'concise';
346
- } else if (interaction.response.length > 500) {
347
- prefs.responseStyle = 'detailed';
348
- }
349
-
350
- this.preferences.set(userId, prefs);
351
- }
352
-
353
- private learnFromFeedback(userId: string, feedback: Feedback): void {
354
- const prefs = this.getPreferences(userId);
355
-
356
- if (feedback.rating >= 4) {
357
- // User liked the response - reinforce current style
358
- } else if (feedback.rating <= 2) {
359
- // User didn't like it - try different approach
360
- prefs.responseStyle = prefs.responseStyle === 'detailed' ? 'concise' : 'detailed';
361
- }
362
-
363
- // Process corrections
364
- if (feedback.corrections && feedback.corrections.length > 0) {
365
- // Learn from corrections
366
- }
367
-
368
- this.preferences.set(userId, prefs);
369
- }
370
-
371
- private extractTopics(text: string): string[] {
372
- return text
373
- .toLowerCase()
374
- .match(/\b\w{5,}\b/g)
375
- ?.filter((w, i, arr) => arr.indexOf(w) === i)
376
- ?.slice(0, 3) || [];
377
- }
378
-
379
- recommendPreferences(userId: string): Partial<UserPreferences> {
380
- const prefs = this.getPreferences(userId);
381
- const recommendations: Partial<UserPreferences> = {};
382
-
383
- // Recommend based on interaction history
384
- if (prefs.topicInterests.length > 5) {
385
- recommendations.topicInterests = prefs.topicInterests.slice(0, 10);
386
- }
387
-
388
- return recommendations;
389
- }
390
- }
391
-
392
- // ============================================================================
393
- // CONTEXT MEMORY MANAGER
394
- // ============================================================================
395
-
396
- class ContextMemoryManager {
397
- private interactions: Map<string, Interaction[]> = new Map();
398
- private maxContextSize = 10;
399
-
400
- addInteraction(sessionId: string, interaction: Interaction): void {
401
- if (!this.interactions.has(sessionId)) {
402
- this.interactions.set(sessionId, []);
403
- }
404
-
405
- const sessionInteractions = this.interactions.get(sessionId)!;
406
- sessionInteractions.push(interaction);
407
-
408
- // Keep only recent interactions
409
- if (sessionInteractions.length > this.maxContextSize) {
410
- sessionInteractions.shift();
411
- }
412
- }
413
-
414
- getContext(sessionId: string): Interaction[] {
415
- return this.interactions.get(sessionId) || [];
416
- }
417
-
418
- getRelevantContext(sessionId: string, query: string): Interaction[] {
419
- const allContext = this.getContext(sessionId);
420
- const queryWords = query.toLowerCase().split(/\s+/);
421
-
422
- return allContext
423
- .map(interaction => ({
424
- interaction,
425
- relevance: this.calculateRelevance(interaction, queryWords)
426
- }))
427
- .filter(({ relevance }) => relevance > 0.3)
428
- .sort((a, b) => b.relevance - a.relevance)
429
- .map(({ interaction }) => interaction);
430
- }
431
-
432
- summarizeContext(sessionId: string): string {
433
- const context = this.getContext(sessionId);
434
- if (context.length === 0) return '';
435
-
436
- const topics = new Set<string>();
437
- const keyPoints: string[] = [];
438
-
439
- context.forEach(interaction => {
440
- const queryTopics = this.extractTopics(interaction.query);
441
- queryTopics.forEach(t => topics.add(t));
442
-
443
- if (interaction.feedback?.helpful) {
444
- keyPoints.push(interaction.response.substring(0, 100));
445
- }
446
- });
447
-
448
- return `Previous topics: ${Array.from(topics).join(', ')}. ` +
449
- `Key points: ${keyPoints.join('; ')}`;
450
- }
451
-
452
- clearContext(sessionId: string): void {
453
- this.interactions.delete(sessionId);
454
- }
455
-
456
- private calculateRelevance(interaction: Interaction, queryWords: string[]): number {
457
- const text = `${interaction.query} ${interaction.response}`.toLowerCase();
458
- const matches = queryWords.filter(qw => text.includes(qw)).length;
459
- return matches / queryWords.length;
460
- }
461
-
462
- private extractTopics(text: string): string[] {
463
- return text
464
- .toLowerCase()
465
- .match(/\b\w{5,}\b/g)
466
- ?.filter((w, i, arr) => arr.indexOf(w) === i)
467
- ?.slice(0, 5) || [];
468
- }
469
- }
470
-
471
- // ============================================================================
472
- // MAIN LEARNING ENGINE
473
- // ============================================================================
474
-
475
- export class LearningEngine extends EventEmitter {
476
- private patternEngine: PatternRecognitionEngine;
477
- private knowledgeGraph: KnowledgeGraphManager;
478
- private preferenceEngine: PreferenceLearningEngine;
479
- private contextManager: ContextMemoryManager;
480
- private contexts: Map<string, LearningContext> = new Map();
481
-
482
- constructor() {
483
- super();
484
- this.patternEngine = new PatternRecognitionEngine();
485
- this.knowledgeGraph = new KnowledgeGraphManager();
486
- this.preferenceEngine = new PreferenceLearningEngine();
487
- this.contextManager = new ContextMemoryManager();
488
- }
489
-
490
- /**
491
- * Create or get learning context for a session
492
- */
493
- getOrCreateContext(sessionId: string, userId?: string): LearningContext {
494
- if (this.contexts.has(sessionId)) {
495
- return this.contexts.get(sessionId)!;
496
- }
497
-
498
- const context: LearningContext = {
499
- id: `ctx_${Date.now()}`,
500
- sessionId,
501
- userId,
502
- topic: '',
503
- previousInteractions: [],
504
- learnedPatterns: [],
505
- knowledgeGraph: this.knowledgeGraph.getGraph(),
506
- preferences: this.preferenceEngine.getPreferences(userId)
507
- };
508
-
509
- this.contexts.set(sessionId, context);
510
- return context;
511
- }
512
-
513
- /**
514
- * Record an interaction and learn from it
515
- */
516
- recordInteraction(
517
- sessionId: string,
518
- query: string,
519
- response: string,
520
- feedback?: Feedback
521
- ): Interaction {
522
- const context = this.getOrCreateContext(sessionId);
523
-
524
- const interaction: Interaction = {
525
- id: `int_${Date.now()}`,
526
- timestamp: new Date(),
527
- query,
528
- response,
529
- feedback,
530
- contextSnapshot: { ...context }
531
- };
532
-
533
- // Add to context memory
534
- this.contextManager.addInteraction(sessionId, interaction);
535
- context.previousInteractions.push(interaction);
536
-
537
- // Learn patterns
538
- const patterns = this.patternEngine.recognize(query, response);
539
- context.learnedPatterns.push(...patterns);
540
-
541
- // Update preferences if userId exists
542
- if (context.userId) {
543
- this.preferenceEngine.learnFromInteraction(context.userId, interaction);
544
- context.preferences = this.preferenceEngine.getPreferences(context.userId);
545
- }
546
-
547
- // Extract and add knowledge
548
- this.extractAndAddKnowledge(query, response);
549
-
550
- this.emit('interaction_recorded', {
551
- id: interaction.id,
552
- stage: ThinkingStage.LEARNING,
553
- timestamp: new Date(),
554
- data: { sessionId, patternsFound: patterns.length }
555
- } as ThinkingEvent);
556
-
557
- return interaction;
558
- }
559
-
560
- /**
561
- * Get relevant context for a query
562
- */
563
- getRelevantContext(sessionId: string, query: string): {
564
- interactions: Interaction[];
565
- patterns: Pattern[];
566
- knowledge: KnowledgeNode[];
567
- summary: string;
568
- } {
569
- const context = this.getOrCreateContext(sessionId);
570
-
571
- // Get relevant interactions
572
- const interactions = this.contextManager.getRelevantContext(sessionId, query);
573
-
574
- // Get relevant patterns
575
- const patterns = this.patternEngine.recognize(query, '');
576
-
577
- // Get relevant knowledge
578
- const knowledge = this.knowledgeGraph.query(query);
579
-
580
- // Get context summary
581
- const summary = this.contextManager.summarizeContext(sessionId);
582
-
583
- return { interactions, patterns, knowledge, summary };
584
- }
585
-
586
- /**
587
- * Add knowledge to the knowledge graph
588
- */
589
- addKnowledge(
590
- label: string,
591
- type: KnowledgeNode['type'],
592
- properties: Record<string, unknown>,
593
- sources: string[]
594
- ): KnowledgeNode {
595
- const node = this.knowledgeGraph.addNode({
596
- label,
597
- type,
598
- properties,
599
- confidence: 0.8,
600
- sources
601
- });
602
-
603
- this.emit('knowledge_added', {
604
- id: node.id,
605
- stage: ThinkingStage.LEARNING,
606
- timestamp: new Date(),
607
- data: { label, type }
608
- } as ThinkingEvent);
609
-
610
- return node;
611
- }
612
-
613
- /**
614
- * Connect knowledge nodes
615
- */
616
- connectKnowledge(
617
- fromId: string,
618
- toId: string,
619
- relation: string,
620
- strength: number,
621
- evidence: string[]
622
- ): void {
623
- this.knowledgeGraph.addEdge(fromId, toId, relation, strength, evidence);
624
- }
625
-
626
- /**
627
- * Query knowledge graph
628
- */
629
- queryKnowledge(query: string): KnowledgeNode[] {
630
- return this.knowledgeGraph.query(query);
631
- }
632
-
633
- /**
634
- * Infer new knowledge
635
- */
636
- inferKnowledge(fromNodeId: string, relationType?: string): KnowledgeNode[] {
637
- return this.knowledgeGraph.infer(fromNodeId, relationType);
638
- }
639
-
640
- /**
641
- * Update user preferences
642
- */
643
- updatePreferences(userId: string, updates: Partial<UserPreferences>): void {
644
- this.preferenceEngine.updatePreferences(userId, updates);
645
- }
646
-
647
- /**
648
- * Get user preferences
649
- */
650
- getPreferences(userId?: string): UserPreferences {
651
- return this.preferenceEngine.getPreferences(userId);
652
- }
653
-
654
- /**
655
- * Get top patterns
656
- */
657
- getTopPatterns(limit?: number): Pattern[] {
658
- return this.patternEngine.getTopPatterns(limit);
659
- }
660
-
661
- /**
662
- * Export knowledge graph
663
- */
664
- exportKnowledgeGraph(): string {
665
- return this.knowledgeGraph.exportGraph();
666
- }
667
-
668
- /**
669
- * Import knowledge graph
670
- */
671
- importKnowledgeGraph(json: string): void {
672
- this.knowledgeGraph.importGraph(json);
673
- }
674
-
675
- private extractAndAddKnowledge(query: string, response: string): void {
676
- // Extract entities from query and response
677
- const entities = this.extractEntities(`${query} ${response}`);
678
-
679
- entities.forEach(entity => {
680
- // Check if entity already exists
681
- const existing = this.knowledgeGraph.query(entity);
682
-
683
- if (existing.length === 0) {
684
- this.addKnowledge(
685
- entity,
686
- 'entity',
687
- { firstSeen: new Date().toISOString() },
688
- ['interaction']
689
- );
690
- }
691
- });
692
-
693
- // Extract concepts
694
- const concepts = this.extractConcepts(response);
695
- concepts.forEach(concept => {
696
- this.addKnowledge(
697
- concept,
698
- 'concept',
699
- { extractedFrom: 'response' },
700
- ['learning_engine']
701
- );
702
- });
703
- }
704
-
705
- private extractEntities(text: string): string[] {
706
- const capitalizedWords = text.match(/\b[A-Z][a-z]+(?:\s+[A-Z][a-z]+)*\b/g) || [];
707
- return [...new Set(capitalizedWords)];
708
- }
709
-
710
- private extractConcepts(text: string): string[] {
711
- return text
712
- .toLowerCase()
713
- .match(/\b\w{6,}\b/g)
714
- ?.filter((w, i, arr) => arr.indexOf(w) === i)
715
- ?.slice(0, 5) || [];
716
- }
717
- }
718
-
719
- // ============================================================================
720
- // EXPORT SINGLETON INSTANCE
721
- // ============================================================================
722
-
723
- export const learningEngine = new LearningEngine();
724
-
725
- // ============================================================================
726
- // EXAMPLE USAGE
727
- // ============================================================================
728
-
729
- /*
730
- // Create learning context
731
- const context = learningEngine.getOrCreateContext('session_123', 'user_456');
732
-
733
- // Record interactions
734
- const interaction1 = learningEngine.recordInteraction(
735
- 'session_123',
736
- 'What are the benefits of TypeScript?',
737
- 'TypeScript offers type safety, better IDE support, and easier refactoring...'
738
- );
739
-
740
- // Add feedback
741
- learningEngine.recordInteraction(
742
- 'session_123',
743
- 'How do I set up TypeScript?',
744
- 'To set up TypeScript, first install it with npm...',
745
- { rating: 5, helpful: true, comments: 'Very helpful!' }
746
- );
747
-
748
- // Get relevant context
749
- const relevant = learningEngine.getRelevantContext(
750
- 'session_123',
751
- 'TypeScript configuration'
752
- );
753
-
754
- // Add knowledge
755
- const node = learningEngine.addKnowledge(
756
- 'TypeScript',
757
- 'concept',
758
- { category: 'programming_language', creator: 'Microsoft' },
759
- ['official_documentation']
760
- );
761
-
762
- // Connect knowledge
763
- learningEngine.connectKnowledge(
764
- node.id,
765
- 'node_javascript',
766
- 'superset_of',
767
- 0.95,
768
- ['TypeScript extends JavaScript']
769
- );
770
-
771
- // Query knowledge
772
- const results = learningEngine.queryKnowledge('programming');
773
-
774
- // Get patterns
775
- const patterns = learningEngine.getTopPatterns(5);
776
-
777
- // Export knowledge graph
778
- const graphJson = learningEngine.exportKnowledgeGraph();
779
- */