gthinking 1.3.0 → 2.1.2

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 +248 -246
  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 +323 -0
  7. package/dist/analysis/analysis-engine.js.map +1 -0
  8. package/dist/core/config.d.ts +1423 -0
  9. package/dist/core/config.d.ts.map +1 -0
  10. package/dist/core/config.js +445 -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 +384 -0
  161. package/src/core/config.ts +462 -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
@@ -0,0 +1,462 @@
1
+ /**
2
+ * Configuration for gthinking v2.0.0
3
+ * Centralized configuration management
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import * as os from 'os';
10
+ import { ConfigurationError } from './errors';
11
+
12
+ /**
13
+ * LLM Provider configuration schema
14
+ */
15
+ export const LLMProviderConfigSchema = z.object({
16
+ provider: z.enum(['gemini', 'claude', 'openai', 'kimi', 'custom', 'cli']),
17
+ apiKey: z.string().optional(), // Made optional for CLI mode
18
+ baseUrl: z.string().url().optional(),
19
+ model: z.string().optional(),
20
+ cliCommand: z.string().default('gemini'),
21
+ cliArgs: z.array(z.string()).default([]), // Extra args e.g. ['--temperature', '0.7']
22
+ cliPromptPassingMethod: z.enum(['stdin', 'arg']).default('stdin'),
23
+ cliPromptFlag: z.string().optional(), // e.g. '-p' if method is 'arg'
24
+ timeout: z.number().positive().default(30000),
25
+ maxRetries: z.number().nonnegative().default(3),
26
+ rateLimitPerMinute: z.number().positive().default(60),
27
+ });
28
+
29
+ export type LLMProviderConfig = z.infer<typeof LLMProviderConfigSchema>;
30
+
31
+ /**
32
+ * Search configuration schema
33
+ */
34
+ export const SearchConfigSchema = z.object({
35
+ enabled: z.boolean().default(true),
36
+ providers: z.array(z.enum(['google', 'bing', 'brave', 'duckduckgo'])).default(['google']),
37
+ apiKeys: z.record(z.string()).default({}),
38
+ maxResults: z.number().positive().max(100).default(10),
39
+ timeout: z.number().positive().default(30000),
40
+ cacheResults: z.boolean().default(true),
41
+ cacheTTL: z.number().positive().default(3600000), // 1 hour
42
+ });
43
+
44
+ export type SearchConfig = z.infer<typeof SearchConfigSchema>;
45
+
46
+ /**
47
+ * Cache configuration schema
48
+ */
49
+ export const CacheConfigSchema = z.object({
50
+ enabled: z.boolean().default(true),
51
+ maxSize: z.number().positive().default(1000),
52
+ defaultTTL: z.number().positive().default(3600000), // 1 hour
53
+ checkInterval: z.number().positive().default(60000), // 1 minute
54
+ persistence: z.enum(['none', 'file', 'redis']).default('none'),
55
+ persistencePath: z.string().optional(),
56
+ });
57
+
58
+ export type CacheConfig = z.infer<typeof CacheConfigSchema>;
59
+
60
+ /**
61
+ * Logging configuration schema
62
+ */
63
+ export const LoggingConfigSchema = z.object({
64
+ level: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
65
+ enableConsole: z.boolean().default(true),
66
+ enableFile: z.boolean().default(false),
67
+ logDir: z.string().default('./logs'),
68
+ maxFiles: z.number().positive().default(5),
69
+ maxSize: z.string().default('10m'),
70
+ });
71
+
72
+ export type LoggingConfig = z.infer<typeof LoggingConfigSchema>;
73
+
74
+ /**
75
+ * Stage configuration schema
76
+ */
77
+ export const StageConfigSchema = z.object({
78
+ enabled: z.boolean().default(true),
79
+ timeout: z.number().positive().default(60000),
80
+ maxRetries: z.number().nonnegative().default(2),
81
+ parallel: z.boolean().default(false),
82
+ required: z.boolean().default(false),
83
+ });
84
+
85
+ export type StageConfig = z.infer<typeof StageConfigSchema>;
86
+
87
+ /**
88
+ * Pipeline configuration schema
89
+ */
90
+ export const PipelineConfigSchema = z.object({
91
+ stages: z.object({
92
+ search: StageConfigSchema.default({}),
93
+ analysis: StageConfigSchema.default({}),
94
+ reasoning: StageConfigSchema.default({}),
95
+ learning: StageConfigSchema.default({}),
96
+ planning: StageConfigSchema.default({}),
97
+ creativity: StageConfigSchema.default({}),
98
+ synthesis: StageConfigSchema.default({}),
99
+ evaluation: StageConfigSchema.default({}),
100
+ }).default({}),
101
+ enableDynamicPipeline: z.boolean().default(true),
102
+ enableStreaming: z.boolean().default(false),
103
+ maxConcurrentStages: z.number().positive().default(3),
104
+ defaultTimeout: z.number().positive().default(300000), // 5 minutes
105
+ errorHandling: z.enum(['stop', 'continue']).default('stop'),
106
+ });
107
+
108
+ export type PipelineConfig = z.infer<typeof PipelineConfigSchema>;
109
+
110
+ /**
111
+ * Main configuration schema
112
+ */
113
+ export const GThinkingConfigSchema = z.object({
114
+ version: z.string().default('2.0.0'),
115
+ llm: LLMProviderConfigSchema.default({ provider: 'gemini' }),
116
+ search: SearchConfigSchema.default({}),
117
+ cache: CacheConfigSchema.default({}),
118
+ logging: LoggingConfigSchema.default({}),
119
+ pipeline: PipelineConfigSchema.default({}),
120
+ security: z.object({
121
+ enableInputSanitization: z.boolean().default(true),
122
+ enableRateLimiting: z.boolean().default(true),
123
+ maxRequestsPerMinute: z.number().positive().default(100),
124
+ maxQueryLength: z.number().positive().default(10000),
125
+ }).default({}),
126
+ session: z.object({
127
+ maxSessions: z.number().positive().default(1000),
128
+ sessionTTL: z.number().positive().default(3600000), // 1 hour
129
+ enablePersistence: z.boolean().default(false),
130
+ persistencePath: z.string().optional(),
131
+ }).default({}),
132
+ metrics: z.object({
133
+ enabled: z.boolean().default(true),
134
+ collectDetailedMetrics: z.boolean().default(false),
135
+ metricsInterval: z.number().positive().default(60000),
136
+ }).default({}),
137
+ });
138
+
139
+ export type GThinkingConfig = z.infer<typeof GThinkingConfigSchema>;
140
+
141
+ /**
142
+ * Default configuration
143
+ */
144
+ export const defaultConfig: GThinkingConfig = {
145
+ version: '2.0.0',
146
+ llm: {
147
+ provider: 'gemini',
148
+ timeout: 30000,
149
+ maxRetries: 3,
150
+ rateLimitPerMinute: 60,
151
+ cliCommand: 'gemini',
152
+ cliArgs: [],
153
+ cliPromptPassingMethod: 'stdin',
154
+ },
155
+ search: {
156
+ enabled: true,
157
+ providers: ['google'],
158
+ apiKeys: {},
159
+ maxResults: 10,
160
+ timeout: 30000,
161
+ cacheResults: true,
162
+ cacheTTL: 3600000,
163
+ },
164
+ cache: {
165
+ enabled: true,
166
+ maxSize: 1000,
167
+ defaultTTL: 3600000,
168
+ checkInterval: 60000,
169
+ persistence: 'none',
170
+ },
171
+ logging: {
172
+ level: 'info',
173
+ enableConsole: true,
174
+ enableFile: false,
175
+ logDir: './logs',
176
+ maxFiles: 5,
177
+ maxSize: '10m',
178
+ },
179
+ pipeline: {
180
+ stages: {
181
+ search: { enabled: true, timeout: 60000, maxRetries: 2, parallel: false, required: false },
182
+ analysis: { enabled: true, timeout: 60000, maxRetries: 2, parallel: false, required: false },
183
+ reasoning: { enabled: true, timeout: 120000, maxRetries: 2, parallel: false, required: false },
184
+ learning: { enabled: true, timeout: 30000, maxRetries: 1, parallel: true, required: false },
185
+ planning: { enabled: true, timeout: 60000, maxRetries: 2, parallel: false, required: false },
186
+ creativity: { enabled: true, timeout: 120000, maxRetries: 2, parallel: false, required: false },
187
+ synthesis: { enabled: true, timeout: 60000, maxRetries: 2, parallel: false, required: true },
188
+ evaluation: { enabled: true, timeout: 30000, maxRetries: 1, parallel: true, required: false },
189
+ },
190
+ enableDynamicPipeline: true,
191
+ enableStreaming: false,
192
+ maxConcurrentStages: 3,
193
+ defaultTimeout: 300000,
194
+ errorHandling: 'stop',
195
+ },
196
+ security: {
197
+ enableInputSanitization: true,
198
+ enableRateLimiting: true,
199
+ maxRequestsPerMinute: 100,
200
+ maxQueryLength: 10000,
201
+ },
202
+ session: {
203
+ maxSessions: 1000,
204
+ sessionTTL: 3600000,
205
+ enablePersistence: false,
206
+ },
207
+ metrics: {
208
+ enabled: true,
209
+ collectDetailedMetrics: false,
210
+ metricsInterval: 60000,
211
+ },
212
+ };
213
+
214
+ /**
215
+ * Configuration manager class
216
+ */
217
+ export class ConfigManager {
218
+ private config: GThinkingConfig;
219
+ private validators: Map<string, (value: unknown) => boolean> = new Map();
220
+
221
+ constructor(initialConfig: Partial<GThinkingConfig> = {}) {
222
+ this.config = this.mergeConfig(defaultConfig, initialConfig);
223
+ this.loadFromMCPConfig();
224
+ this.loadFromEnvironment();
225
+ this.validateConfig();
226
+ }
227
+
228
+ /**
229
+ * Load configuration from ~/.gemini/settings.json if it exists
230
+ */
231
+ public loadFromMCPConfig(): void {
232
+ try {
233
+ const homeDir = os.homedir();
234
+ const configPath = path.join(homeDir, '.gemini', 'settings.json');
235
+
236
+ if (fs.existsSync(configPath)) {
237
+ const fileContent = fs.readFileSync(configPath, 'utf-8');
238
+ const settings = JSON.parse(fileContent);
239
+
240
+ // Check for gthinking specific config or generic mcpServers config
241
+ const gthinkingConfig = settings.mcpServers?.gthinking;
242
+
243
+ if (gthinkingConfig && gthinkingConfig.env) {
244
+ const envConfig: Partial<GThinkingConfig> = {};
245
+ const env = gthinkingConfig.env;
246
+
247
+ // Map env vars from settings.json to config
248
+ if (env.GTHINKING_LLM_PROVIDER) {
249
+ envConfig.llm = {
250
+ ...this.config.llm,
251
+ provider: env.GTHINKING_LLM_PROVIDER,
252
+ };
253
+ }
254
+ if (env.GTHINKING_LLM_API_KEY) {
255
+ envConfig.llm = {
256
+ ...envConfig.llm,
257
+ ...this.config.llm,
258
+ apiKey: env.GTHINKING_LLM_API_KEY,
259
+ };
260
+ }
261
+ if (env.GTHINKING_LLM_CLI_COMMAND) {
262
+ envConfig.llm = {
263
+ ...envConfig.llm,
264
+ ...this.config.llm,
265
+ cliCommand: env.GTHINKING_LLM_CLI_COMMAND,
266
+ };
267
+ }
268
+ // Add other mappings as needed...
269
+
270
+ this.updateConfig(envConfig);
271
+ }
272
+ }
273
+ } catch (error) {
274
+ // Ignore errors when loading optional config file
275
+ // logger.warn('Failed to load MCP settings', { error });
276
+ }
277
+ }
278
+
279
+ /**
280
+ * Get the current configuration
281
+ * @returns The current configuration
282
+ */
283
+ public getConfig(): GThinkingConfig {
284
+ return { ...this.config };
285
+ }
286
+
287
+ /**
288
+ * Get a specific configuration value
289
+ * @param path - The configuration path (e.g., 'llm.provider')
290
+ * @returns The configuration value
291
+ */
292
+ public get<T>(path: string): T | undefined {
293
+ const parts = path.split('.');
294
+ let current: unknown = this.config;
295
+
296
+ for (const part of parts) {
297
+ if (current === null || current === undefined) {
298
+ return undefined;
299
+ }
300
+ current = (current as Record<string, unknown>)[part];
301
+ }
302
+
303
+ return current as T;
304
+ }
305
+
306
+ /**
307
+ * Update the configuration
308
+ * @param updates - Configuration updates
309
+ */
310
+ public updateConfig(updates: Partial<GThinkingConfig>): void {
311
+ this.config = this.mergeConfig(this.config, updates);
312
+ this.validateConfig();
313
+ }
314
+
315
+ /**
316
+ * Update a specific configuration value
317
+ * @param path - The configuration path
318
+ * @param value - The new value
319
+ */
320
+ public set<T>(path: string, value: T): void {
321
+ const parts = path.split('.');
322
+ let current: Record<string, unknown> = this.config as Record<string, unknown>;
323
+
324
+ for (let i = 0; i < parts.length - 1; i++) {
325
+ const part = parts[i];
326
+ if (!(part in current)) {
327
+ current[part] = {};
328
+ }
329
+ current = current[part] as Record<string, unknown>;
330
+ }
331
+
332
+ current[parts[parts.length - 1]] = value;
333
+ this.validateConfig();
334
+ }
335
+
336
+ /**
337
+ * Load configuration from environment variables
338
+ */
339
+ public loadFromEnvironment(): void {
340
+ const envConfig: Partial<GThinkingConfig> = {};
341
+
342
+ // LLM configuration
343
+ if (process.env.GTHINKING_LLM_PROVIDER) {
344
+ envConfig.llm = {
345
+ ...this.config.llm,
346
+ provider: process.env.GTHINKING_LLM_PROVIDER as 'gemini' | 'claude' | 'openai' | 'kimi' | 'custom',
347
+ };
348
+ }
349
+ if (process.env.GTHINKING_LLM_API_KEY) {
350
+ envConfig.llm = {
351
+ ...envConfig.llm,
352
+ ...this.config.llm,
353
+ apiKey: process.env.GTHINKING_LLM_API_KEY,
354
+ };
355
+ }
356
+ if (process.env.GTHINKING_LLM_CLI_COMMAND) {
357
+ envConfig.llm = {
358
+ ...envConfig.llm,
359
+ ...this.config.llm,
360
+ cliCommand: process.env.GTHINKING_LLM_CLI_COMMAND,
361
+ };
362
+ }
363
+ if (process.env.GTHINKING_LLM_CLI_ARGS) {
364
+ // Expect comma-separated args
365
+ const args = process.env.GTHINKING_LLM_CLI_ARGS.split(',').map(s => s.trim());
366
+ envConfig.llm = { ...envConfig.llm, ...this.config.llm, cliArgs: args };
367
+ }
368
+ if (process.env.GTHINKING_LLM_CLI_PROMPT_METHOD) {
369
+ envConfig.llm = {
370
+ ...envConfig.llm,
371
+ ...this.config.llm,
372
+ cliPromptPassingMethod: process.env.GTHINKING_LLM_CLI_PROMPT_METHOD as 'stdin' | 'arg'
373
+ };
374
+ }
375
+ if (process.env.GTHINKING_LLM_CLI_PROMPT_FLAG) {
376
+ envConfig.llm = { ...envConfig.llm, ...this.config.llm, cliPromptFlag: process.env.GTHINKING_LLM_CLI_PROMPT_FLAG };
377
+ }
378
+
379
+ // Search configuration
380
+ if (process.env.GTHINKING_SEARCH_API_KEY) {
381
+ envConfig.search = {
382
+ ...this.config.search,
383
+ apiKeys: { google: process.env.GTHINKING_SEARCH_API_KEY },
384
+ };
385
+ }
386
+
387
+ // Logging configuration
388
+ if (process.env.GTHINKING_LOG_LEVEL) {
389
+ envConfig.logging = {
390
+ ...this.config.logging,
391
+ level: process.env.GTHINKING_LOG_LEVEL as 'debug' | 'info' | 'warn' | 'error',
392
+ };
393
+ }
394
+
395
+ this.updateConfig(envConfig);
396
+ }
397
+
398
+ /**
399
+ * Register a custom validator
400
+ * @param path - The configuration path
401
+ * @param validator - The validator function
402
+ */
403
+ public registerValidator(path: string, validator: (value: unknown) => boolean): void {
404
+ this.validators.set(path, validator);
405
+ }
406
+
407
+ /**
408
+ * Merge configurations
409
+ * @param base - Base configuration
410
+ * @param override - Override configuration
411
+ * @returns Merged configuration
412
+ */
413
+ private mergeConfig(
414
+ base: GThinkingConfig,
415
+ override: Partial<GThinkingConfig>
416
+ ): GThinkingConfig {
417
+ return {
418
+ ...base,
419
+ ...override,
420
+ llm: { ...base.llm, ...override.llm },
421
+ search: { ...base.search, ...override.search },
422
+ cache: { ...base.cache, ...override.cache },
423
+ logging: { ...base.logging, ...override.logging },
424
+ pipeline: {
425
+ ...base.pipeline,
426
+ ...override.pipeline,
427
+ stages: {
428
+ ...base.pipeline.stages,
429
+ ...override.pipeline?.stages,
430
+ },
431
+ },
432
+ security: { ...base.security, ...override.security },
433
+ session: { ...base.session, ...override.session },
434
+ metrics: { ...base.metrics, ...override.metrics },
435
+ };
436
+ }
437
+
438
+ /**
439
+ * Validate the configuration
440
+ */
441
+ private validateConfig(): void {
442
+ const result = GThinkingConfigSchema.safeParse(this.config);
443
+
444
+ if (!result.success) {
445
+ throw new ConfigurationError(
446
+ 'Invalid configuration: ' + result.error.message,
447
+ { errors: result.error.errors }
448
+ );
449
+ }
450
+
451
+ // Run custom validators
452
+ for (const [path, validator] of this.validators) {
453
+ const value = this.get(path);
454
+ if (!validator(value)) {
455
+ throw new ConfigurationError(`Validation failed for ${path}`);
456
+ }
457
+ }
458
+ }
459
+ }
460
+
461
+ // Export a singleton instance
462
+ export const configManager = new ConfigManager();