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