thatgfsj-code 0.3.0 → 0.3.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 (262) hide show
  1. package/CHANGELOG.md +229 -0
  2. package/DEVELOPMENT.md +286 -0
  3. package/README.md +144 -79
  4. package/dist/agent/core.d.ts +56 -0
  5. package/dist/agent/core.d.ts.map +1 -0
  6. package/dist/agent/core.js +142 -0
  7. package/dist/agent/core.js.map +1 -0
  8. package/dist/agent/index.d.ts +8 -0
  9. package/dist/agent/index.d.ts.map +1 -0
  10. package/dist/agent/index.js +8 -0
  11. package/dist/agent/index.js.map +1 -0
  12. package/dist/agent/intent.d.ts +36 -0
  13. package/dist/agent/intent.d.ts.map +1 -0
  14. package/dist/agent/intent.js +146 -0
  15. package/dist/agent/intent.js.map +1 -0
  16. package/dist/agent/streaming.d.ts +50 -0
  17. package/dist/agent/streaming.d.ts.map +1 -0
  18. package/dist/agent/streaming.js +110 -0
  19. package/dist/agent/streaming.js.map +1 -0
  20. package/dist/core/ai-engine.d.ts +76 -0
  21. package/dist/core/ai-engine.d.ts.map +1 -0
  22. package/dist/core/ai-engine.js +394 -0
  23. package/dist/core/ai-engine.js.map +1 -0
  24. package/dist/core/cli.d.ts +21 -0
  25. package/dist/core/cli.d.ts.map +1 -0
  26. package/dist/core/cli.js +143 -0
  27. package/dist/core/cli.js.map +1 -0
  28. package/dist/core/config.d.ts +55 -0
  29. package/dist/core/config.d.ts.map +1 -0
  30. package/dist/core/config.js +162 -0
  31. package/dist/core/config.js.map +1 -0
  32. package/dist/core/context-compactor.d.ts +54 -0
  33. package/dist/core/context-compactor.d.ts.map +1 -0
  34. package/dist/core/context-compactor.js +197 -0
  35. package/dist/core/context-compactor.js.map +1 -0
  36. package/dist/core/hooks.d.ts +75 -0
  37. package/dist/core/hooks.d.ts.map +1 -0
  38. package/dist/core/hooks.js +146 -0
  39. package/dist/core/hooks.js.map +1 -0
  40. package/dist/core/permissions.d.ts +52 -0
  41. package/dist/core/permissions.d.ts.map +1 -0
  42. package/dist/core/permissions.js +237 -0
  43. package/dist/core/permissions.js.map +1 -0
  44. package/dist/core/session.d.ts +54 -0
  45. package/dist/core/session.d.ts.map +1 -0
  46. package/dist/core/session.js +147 -0
  47. package/dist/core/session.js.map +1 -0
  48. package/dist/core/skills.d.ts +60 -0
  49. package/dist/core/skills.d.ts.map +1 -0
  50. package/dist/core/skills.js +175 -0
  51. package/dist/core/skills.js.map +1 -0
  52. package/dist/core/state.d.ts +60 -0
  53. package/dist/core/state.d.ts.map +1 -0
  54. package/dist/core/state.js +106 -0
  55. package/dist/core/state.js.map +1 -0
  56. package/dist/core/subagent.d.ts +68 -0
  57. package/dist/core/subagent.d.ts.map +1 -0
  58. package/dist/core/subagent.js +142 -0
  59. package/dist/core/subagent.js.map +1 -0
  60. package/dist/core/system-prompt.d.ts +40 -0
  61. package/dist/core/system-prompt.d.ts.map +1 -0
  62. package/dist/core/system-prompt.js +138 -0
  63. package/dist/core/system-prompt.js.map +1 -0
  64. package/dist/core/tool-registry.d.ts +53 -0
  65. package/dist/core/tool-registry.d.ts.map +1 -0
  66. package/dist/core/tool-registry.js +138 -0
  67. package/dist/core/tool-registry.js.map +1 -0
  68. package/dist/core/types.d.ts +206 -0
  69. package/dist/core/types.d.ts.map +1 -0
  70. package/dist/core/types.js +127 -0
  71. package/dist/core/types.js.map +1 -0
  72. package/dist/index.d.ts +7 -0
  73. package/dist/{cmd/index.d.ts.map → index.d.ts.map} +1 -1
  74. package/dist/index.js +472 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/mcp/client.d.ts +1 -1
  77. package/dist/mcp/client.d.ts.map +1 -1
  78. package/dist/repl/index.d.ts +8 -0
  79. package/dist/repl/index.d.ts.map +1 -0
  80. package/dist/repl/index.js +8 -0
  81. package/dist/repl/index.js.map +1 -0
  82. package/dist/repl/input.d.ts +69 -0
  83. package/dist/repl/input.d.ts.map +1 -0
  84. package/dist/repl/input.js +139 -0
  85. package/dist/repl/input.js.map +1 -0
  86. package/dist/repl/loop.d.ts +184 -0
  87. package/dist/repl/loop.d.ts.map +1 -0
  88. package/dist/repl/loop.js +932 -0
  89. package/dist/repl/loop.js.map +1 -0
  90. package/dist/repl/output.d.ts +105 -0
  91. package/dist/repl/output.d.ts.map +1 -0
  92. package/dist/repl/output.js +199 -0
  93. package/dist/repl/output.js.map +1 -0
  94. package/dist/repl/welcome.d.ts +68 -0
  95. package/dist/repl/welcome.d.ts.map +1 -0
  96. package/dist/repl/welcome.js +254 -0
  97. package/dist/repl/welcome.js.map +1 -0
  98. package/dist/tools/file.d.ts +1 -1
  99. package/dist/tools/file.d.ts.map +1 -1
  100. package/dist/tools/git.d.ts +1 -1
  101. package/dist/tools/git.d.ts.map +1 -1
  102. package/dist/tools/index.d.ts +15 -35
  103. package/dist/tools/index.d.ts.map +1 -1
  104. package/dist/tools/index.js +31 -80
  105. package/dist/tools/index.js.map +1 -1
  106. package/dist/tools/search.d.ts +1 -1
  107. package/dist/tools/search.d.ts.map +1 -1
  108. package/dist/tools/shell.d.ts +11 -4
  109. package/dist/tools/shell.d.ts.map +1 -1
  110. package/dist/tools/shell.js +78 -42
  111. package/dist/tools/shell.js.map +1 -1
  112. package/dist/utils/diff-preview.d.ts +42 -0
  113. package/dist/utils/diff-preview.d.ts.map +1 -0
  114. package/dist/utils/diff-preview.js +174 -0
  115. package/dist/utils/diff-preview.js.map +1 -0
  116. package/dist/utils/index.d.ts +8 -0
  117. package/dist/utils/index.d.ts.map +1 -0
  118. package/dist/utils/index.js +8 -0
  119. package/dist/utils/index.js.map +1 -0
  120. package/dist/utils/memory.d.ts +81 -0
  121. package/dist/utils/memory.d.ts.map +1 -0
  122. package/dist/utils/memory.js +186 -0
  123. package/dist/utils/memory.js.map +1 -0
  124. package/dist/utils/project-context.d.ts +62 -0
  125. package/dist/utils/project-context.d.ts.map +1 -0
  126. package/dist/utils/project-context.js +197 -0
  127. package/dist/utils/project-context.js.map +1 -0
  128. package/docs/API_KEY_GUIDE.md +6 -0
  129. package/docs/FAQ.md +25 -3
  130. package/package.json +41 -9
  131. package/ROADMAP.md +0 -61
  132. package/dist/app/agent.d.ts +0 -31
  133. package/dist/app/agent.d.ts.map +0 -1
  134. package/dist/app/agent.js +0 -106
  135. package/dist/app/agent.js.map +0 -1
  136. package/dist/app/index.d.ts +0 -39
  137. package/dist/app/index.d.ts.map +0 -1
  138. package/dist/app/index.js +0 -80
  139. package/dist/app/index.js.map +0 -1
  140. package/dist/cmd/index.d.ts +0 -12
  141. package/dist/cmd/index.js +0 -85
  142. package/dist/cmd/index.js.map +0 -1
  143. package/dist/config/index.d.ts +0 -39
  144. package/dist/config/index.d.ts.map +0 -1
  145. package/dist/config/index.js +0 -110
  146. package/dist/config/index.js.map +0 -1
  147. package/dist/config/providers.d.ts +0 -23
  148. package/dist/config/providers.d.ts.map +0 -1
  149. package/dist/config/providers.js +0 -152
  150. package/dist/config/providers.js.map +0 -1
  151. package/dist/config/types.d.ts +0 -33
  152. package/dist/config/types.d.ts.map +0 -1
  153. package/dist/config/types.js +0 -5
  154. package/dist/config/types.js.map +0 -1
  155. package/dist/hooks/index.d.ts +0 -31
  156. package/dist/hooks/index.d.ts.map +0 -1
  157. package/dist/hooks/index.js +0 -71
  158. package/dist/hooks/index.js.map +0 -1
  159. package/dist/llm/anthropic.d.ts +0 -17
  160. package/dist/llm/anthropic.d.ts.map +0 -1
  161. package/dist/llm/anthropic.js +0 -126
  162. package/dist/llm/anthropic.js.map +0 -1
  163. package/dist/llm/gemini.d.ts +0 -16
  164. package/dist/llm/gemini.d.ts.map +0 -1
  165. package/dist/llm/gemini.js +0 -107
  166. package/dist/llm/gemini.js.map +0 -1
  167. package/dist/llm/index.d.ts +0 -48
  168. package/dist/llm/index.d.ts.map +0 -1
  169. package/dist/llm/index.js +0 -174
  170. package/dist/llm/index.js.map +0 -1
  171. package/dist/llm/openai.d.ts +0 -17
  172. package/dist/llm/openai.d.ts.map +0 -1
  173. package/dist/llm/openai.js +0 -113
  174. package/dist/llm/openai.js.map +0 -1
  175. package/dist/llm/provider.d.ts +0 -33
  176. package/dist/llm/provider.d.ts.map +0 -1
  177. package/dist/llm/provider.js +0 -6
  178. package/dist/llm/provider.js.map +0 -1
  179. package/dist/prompts/index.d.ts +0 -27
  180. package/dist/prompts/index.d.ts.map +0 -1
  181. package/dist/prompts/index.js +0 -102
  182. package/dist/prompts/index.js.map +0 -1
  183. package/dist/session/compactor.d.ts +0 -48
  184. package/dist/session/compactor.d.ts.map +0 -1
  185. package/dist/session/compactor.js +0 -77
  186. package/dist/session/compactor.js.map +0 -1
  187. package/dist/session/index.d.ts +0 -48
  188. package/dist/session/index.d.ts.map +0 -1
  189. package/dist/session/index.js +0 -69
  190. package/dist/session/index.js.map +0 -1
  191. package/dist/session/message.d.ts +0 -26
  192. package/dist/session/message.d.ts.map +0 -1
  193. package/dist/session/message.js +0 -34
  194. package/dist/session/message.js.map +0 -1
  195. package/dist/tools/types.d.ts +0 -68
  196. package/dist/tools/types.d.ts.map +0 -1
  197. package/dist/tools/types.js +0 -57
  198. package/dist/tools/types.js.map +0 -1
  199. package/dist/tui/index.d.ts +0 -8
  200. package/dist/tui/index.d.ts.map +0 -1
  201. package/dist/tui/index.js +0 -8
  202. package/dist/tui/index.js.map +0 -1
  203. package/dist/tui/input.d.ts +0 -14
  204. package/dist/tui/input.d.ts.map +0 -1
  205. package/dist/tui/input.js +0 -50
  206. package/dist/tui/input.js.map +0 -1
  207. package/dist/tui/output.d.ts +0 -20
  208. package/dist/tui/output.d.ts.map +0 -1
  209. package/dist/tui/output.js +0 -70
  210. package/dist/tui/output.js.map +0 -1
  211. package/dist/tui/repl.d.ts +0 -25
  212. package/dist/tui/repl.d.ts.map +0 -1
  213. package/dist/tui/repl.js +0 -114
  214. package/dist/tui/repl.js.map +0 -1
  215. package/dist/tui/welcome.d.ts +0 -15
  216. package/dist/tui/welcome.d.ts.map +0 -1
  217. package/dist/tui/welcome.js +0 -86
  218. package/dist/tui/welcome.js.map +0 -1
  219. package/dist/types.d.ts +0 -38
  220. package/dist/types.d.ts.map +0 -1
  221. package/dist/types.js +0 -6
  222. package/dist/types.js.map +0 -1
  223. package/dist/utils/diff.d.ts +0 -22
  224. package/dist/utils/diff.d.ts.map +0 -1
  225. package/dist/utils/diff.js +0 -60
  226. package/dist/utils/diff.js.map +0 -1
  227. package/dist/utils/project.d.ts +0 -32
  228. package/dist/utils/project.d.ts.map +0 -1
  229. package/dist/utils/project.js +0 -89
  230. package/dist/utils/project.js.map +0 -1
  231. package/src/app/agent.ts +0 -140
  232. package/src/app/index.ts +0 -101
  233. package/src/cmd/index.ts +0 -96
  234. package/src/config/index.ts +0 -130
  235. package/src/config/providers.ts +0 -160
  236. package/src/config/types.ts +0 -46
  237. package/src/hooks/index.ts +0 -111
  238. package/src/llm/anthropic.ts +0 -146
  239. package/src/llm/gemini.ts +0 -127
  240. package/src/llm/index.ts +0 -209
  241. package/src/llm/openai.ts +0 -132
  242. package/src/llm/provider.ts +0 -38
  243. package/src/mcp/client.ts +0 -330
  244. package/src/prompts/index.ts +0 -123
  245. package/src/session/compactor.ts +0 -103
  246. package/src/session/index.ts +0 -81
  247. package/src/session/message.ts +0 -42
  248. package/src/tools/file.ts +0 -117
  249. package/src/tools/git.ts +0 -132
  250. package/src/tools/index.ts +0 -108
  251. package/src/tools/search.ts +0 -263
  252. package/src/tools/shell.ts +0 -136
  253. package/src/tools/types.ts +0 -122
  254. package/src/tui/index.ts +0 -8
  255. package/src/tui/input.ts +0 -56
  256. package/src/tui/output.ts +0 -83
  257. package/src/tui/repl.ts +0 -131
  258. package/src/tui/welcome.ts +0 -101
  259. package/src/types.ts +0 -42
  260. package/src/utils/diff.ts +0 -71
  261. package/src/utils/project.ts +0 -99
  262. package/tsconfig.json +0 -19
@@ -0,0 +1,394 @@
1
+ /**
2
+ * AI Engine - Core AI interaction module
3
+ * Supports multiple providers: MiniMax, SiliconFlow, OpenAI, Anthropic
4
+ *
5
+ * Implements S01: Agent Loop pattern with async generator for streaming
6
+ * Core pattern: while(true) { response → execute tools → append results → repeat }
7
+ */
8
+ import chalk from 'chalk';
9
+ export class AIEngine {
10
+ config;
11
+ tools = new Map();
12
+ constructor(config) {
13
+ this.config = config;
14
+ }
15
+ /**
16
+ * Replace the active configuration at runtime.
17
+ * Used by the REPL `/model` / `/provider` commands — the next streamed
18
+ * request will pick up the new model / baseUrl / provider.
19
+ */
20
+ updateConfig(config) {
21
+ this.config = config;
22
+ }
23
+ /**
24
+ * Inspect a snapshot of the active configuration (read-only).
25
+ */
26
+ getConfig() {
27
+ return this.config;
28
+ }
29
+ /**
30
+ * Register tools for function calling
31
+ */
32
+ registerTool(tool) {
33
+ this.tools.set(tool.name, tool);
34
+ }
35
+ /**
36
+ * Unregister a tool
37
+ */
38
+ unregisterTool(name) {
39
+ this.tools.delete(name);
40
+ }
41
+ /**
42
+ * Get registered tools for API (S02: uses ToolRegistry if available)
43
+ */
44
+ getToolsForAPI() {
45
+ // If registry is injected, use its getToolsForAPI
46
+ if (this.registry) {
47
+ return this.registry.getToolsForAPI();
48
+ }
49
+ // Fallback: build from tools map
50
+ return Array.from(this.tools.values()).map(tool => ({
51
+ type: 'function',
52
+ function: {
53
+ name: tool.name,
54
+ description: tool.description,
55
+ parameters: {
56
+ type: 'object',
57
+ properties: tool.parameters.reduce((acc, p) => {
58
+ acc[p.name] = { type: p.type, description: p.description };
59
+ return acc;
60
+ }, {}),
61
+ required: tool.parameters.filter(p => p.required).map(p => p.name)
62
+ }
63
+ }
64
+ }));
65
+ }
66
+ // S02: Inject registry for enhanced tool management
67
+ setRegistry(registry) {
68
+ this.registry = registry;
69
+ }
70
+ registry;
71
+ // S08: Hook manager
72
+ setHooks(hooks) {
73
+ this.hooks = hooks;
74
+ }
75
+ hooks = null;
76
+ // ==================== S01: Async Generator Agent Loop ====================
77
+ async *chatStream(messages, maxIterations = 10) {
78
+ let currentMessages = [...messages];
79
+ let iterations = 0;
80
+ while (iterations < maxIterations) {
81
+ iterations++;
82
+ // S08 Hook: beforeAgentLoop
83
+ if (this.hooks) {
84
+ await this.hooks.emit('beforeAgentLoop', { messages: currentMessages, iteration: iterations });
85
+ }
86
+ let fullResponse = '';
87
+ for await (const chunk of this.streamRequest(currentMessages)) {
88
+ fullResponse += chunk;
89
+ yield chunk;
90
+ }
91
+ const response = this.parseResponse(fullResponse);
92
+ if (response.tool_calls && response.tool_calls.length > 0) {
93
+ currentMessages.push({
94
+ role: 'assistant',
95
+ content: response.content,
96
+ tool_calls: response.tool_calls
97
+ });
98
+ // Execute each tool
99
+ for (const toolCall of response.tool_calls) {
100
+ // S08 Hook: beforeToolCall
101
+ if (this.hooks) {
102
+ await this.hooks.emit('beforeToolCall', {
103
+ toolName: toolCall.function.name,
104
+ toolParams: JSON.parse(toolCall.function.arguments || '{}'),
105
+ toolCallId: toolCall.id
106
+ });
107
+ }
108
+ const result = await this.executeToolCall(toolCall);
109
+ // S08 Hook: afterToolCall
110
+ if (this.hooks) {
111
+ await this.hooks.emit('afterToolCall', {
112
+ toolName: toolCall.function.name,
113
+ toolParams: JSON.parse(toolCall.function.arguments || '{}'),
114
+ toolResult: result,
115
+ toolCallId: toolCall.id
116
+ });
117
+ }
118
+ const toolResultMsg = {
119
+ role: 'tool',
120
+ content: result.output || result.error || '',
121
+ tool_call_id: toolCall.id,
122
+ name: toolCall.function.name
123
+ };
124
+ currentMessages.push(toolResultMsg);
125
+ yield `\n${chalk.gray(`[tool: ${toolCall.function.name}]`)}`;
126
+ }
127
+ continue;
128
+ }
129
+ // No tool calls — exit loop
130
+ if (response.content) {
131
+ currentMessages.push({
132
+ role: 'assistant',
133
+ content: response.content
134
+ });
135
+ }
136
+ // S08 Hook: afterAgentLoop
137
+ if (this.hooks) {
138
+ await this.hooks.emit('afterAgentLoop', { messages: currentMessages, iteration: iterations });
139
+ }
140
+ return response;
141
+ }
142
+ // Max iterations reached
143
+ return {
144
+ content: '[Agent loop exceeded maximum iterations]',
145
+ role: 'assistant'
146
+ };
147
+ }
148
+ /**
149
+ * S01 Core: Stream request — yields chunks as they arrive
150
+ * Uses async generator for backpressure control and lazy evaluation
151
+ */
152
+ async *streamRequest(messages) {
153
+ const apiKey = this.config.apiKey || this.getApiKey();
154
+ if (!apiKey) {
155
+ // Mock streaming for demo
156
+ const mock = this.getMockResponse(messages);
157
+ for (const char of mock) {
158
+ await new Promise(r => setTimeout(r, 10));
159
+ yield char;
160
+ }
161
+ return;
162
+ }
163
+ const isAnthropicFormat = this.config.provider === 'anthropic' || this.config.provider === 'minimax';
164
+ const isGeminiFormat = this.config.provider === 'gemini';
165
+ let url;
166
+ let headers = {};
167
+ let body;
168
+ if (isGeminiFormat) {
169
+ url = `${this.config.baseUrl}/models/${this.config.model}:generateContent`;
170
+ headers = { 'Content-Type': 'application/json' };
171
+ body = this.buildGeminiRequest(messages);
172
+ }
173
+ else if (isAnthropicFormat) {
174
+ url = `${this.config.baseUrl}/messages-stream`;
175
+ headers = {
176
+ 'Content-Type': 'application/json',
177
+ 'x-api-key': apiKey,
178
+ 'anthropic-version': '2023-06-01',
179
+ 'anthropic-dangerous-direct-browser-access': 'true'
180
+ };
181
+ body = this.buildAnthropicRequest(messages, true);
182
+ }
183
+ else {
184
+ url = `${this.config.baseUrl}/chat/completions`;
185
+ headers = {
186
+ 'Content-Type': 'application/json',
187
+ 'Authorization': `Bearer ${apiKey}`
188
+ };
189
+ body = this.buildOpenAIRequest(messages, true);
190
+ }
191
+ const response = await fetch(url, {
192
+ method: 'POST',
193
+ headers,
194
+ body: JSON.stringify(body)
195
+ });
196
+ if (!response.ok || !response.body) {
197
+ yield `\n${chalk.red(`[API Error: ${response.status}]`)}`;
198
+ return;
199
+ }
200
+ const decoder = new TextDecoder();
201
+ const reader = response.body.getReader();
202
+ try {
203
+ while (true) {
204
+ const { done, value } = await reader.read();
205
+ if (done)
206
+ break;
207
+ const chunk = decoder.decode(value, { stream: true });
208
+ const text = this.extractChunkText(chunk, isAnthropicFormat, isGeminiFormat);
209
+ if (text) {
210
+ yield text;
211
+ }
212
+ }
213
+ }
214
+ finally {
215
+ reader.releaseLock();
216
+ }
217
+ }
218
+ /**
219
+ * Extract text from streaming chunk based on provider format
220
+ */
221
+ extractChunkText(chunk, isAnthropic, isGemini) {
222
+ if (isAnthropic) {
223
+ // Anthropic streaming format: data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"..."}}
224
+ const match = chunk.match(/"type"\s*:\s*"text_delta"\s*,\s*"text"\s*:\s*"([^"]*)"/);
225
+ return match ? match[1] : '';
226
+ }
227
+ else if (isGemini) {
228
+ // Gemini format
229
+ const match = chunk.match(/"text"\s*:\s*"([^"]*)"/);
230
+ return match ? match[1] : '';
231
+ }
232
+ else {
233
+ // OpenAI SSE format: data: {"choices":[{"delta":{"content":"..."}}]}
234
+ const lines = chunk.split('\n');
235
+ for (const line of lines) {
236
+ if (line.startsWith('data: ') && line !== 'data: [DONE]') {
237
+ try {
238
+ const data = JSON.parse(line.slice(6));
239
+ const content = data.choices?.[0]?.delta?.content;
240
+ if (content)
241
+ return content;
242
+ }
243
+ catch {
244
+ // Skip invalid JSON
245
+ }
246
+ }
247
+ }
248
+ return '';
249
+ }
250
+ }
251
+ /**
252
+ * Parse full response text into structured AIResponse
253
+ */
254
+ parseResponse(fullText) {
255
+ // For now return content as-is; tool call parsing happens via content patterns
256
+ return {
257
+ content: fullText,
258
+ role: 'assistant',
259
+ tool_calls: this.extractToolCalls(fullText)
260
+ };
261
+ }
262
+ /**
263
+ * Extract tool calls from response content
264
+ *
265
+ * NOTE: 当前为占位实现,实际不会从流式内容中解析工具调用。这意味着
266
+ * `chatStream` 内的 `if (response.tool_calls ...)` 分支永远不会进入,
267
+ * 已注册的 `Tool` 不会被调用,Agent 等价于一个聊天客户端。这是有意为之的
268
+ * 局限性 — 真实工具调用解析需要每个提供商走 JSON mode / native tool_calls
269
+ * 流(chunks 里的 `delta.tool_calls` 已被 `extractChunkText` 丢弃)。
270
+ * 修复此问题需要更大的重构,不属于 0.2.2 patch 的范围。
271
+ */
272
+ extractToolCalls(_content) {
273
+ return undefined;
274
+ }
275
+ // ==================== Legacy chat() — delegates to chatStream ====================
276
+ /**
277
+ * Original non-streaming chat — now implemented via chatStream
278
+ */
279
+ async chat(messages, maxIterations = 5) {
280
+ let fullContent = '';
281
+ for await (const chunk of this.chatStream(messages, maxIterations)) {
282
+ fullContent += chunk;
283
+ }
284
+ return {
285
+ content: fullContent,
286
+ role: 'assistant'
287
+ };
288
+ }
289
+ // ==================== Tool Execution ====================
290
+ async executeToolCall(toolCall) {
291
+ const { name, arguments: args } = toolCall.function;
292
+ const tool = this.tools.get(name);
293
+ if (!tool) {
294
+ return { error: `Tool "${name}" not found` };
295
+ }
296
+ try {
297
+ const params = JSON.parse(args);
298
+ const result = await tool.execute(params, {
299
+ confirmAction: async (msg) => {
300
+ console.log(chalk.yellow(`\n⚠️ Tool wants to execute: ${msg}`));
301
+ return false; // Default deny in CLI mode
302
+ }
303
+ });
304
+ return {
305
+ output: result.success ? (result.output || JSON.stringify(result.data)) : undefined,
306
+ error: result.error
307
+ };
308
+ }
309
+ catch (error) {
310
+ return { error: `Tool execution failed: ${error.message}` };
311
+ }
312
+ }
313
+ // ==================== Request Builders ====================
314
+ buildOpenAIRequest(messages, stream) {
315
+ const tools = this.getToolsForAPI();
316
+ return {
317
+ model: this.config.model || 'Qwen/Qwen2.5-7B-Instruct',
318
+ messages: messages.map(m => ({
319
+ role: m.role,
320
+ content: m.content,
321
+ name: m.name,
322
+ tool_call_id: m.tool_call_id,
323
+ tool_calls: m.tool_calls
324
+ })),
325
+ temperature: this.config.temperature || 0.7,
326
+ max_tokens: this.config.maxTokens || 4096,
327
+ stream,
328
+ ...(tools.length > 0 && { tools })
329
+ };
330
+ }
331
+ buildAnthropicRequest(messages, stream) {
332
+ const anthropicMessages = messages
333
+ .filter(m => m.role !== 'system')
334
+ .map(m => ({
335
+ role: m.role === 'assistant' ? 'assistant' : 'user',
336
+ content: m.content
337
+ }));
338
+ return {
339
+ model: this.config.model || 'claude-3-haiku-20240307',
340
+ messages: anthropicMessages,
341
+ max_tokens: this.config.maxTokens || 4096,
342
+ temperature: this.config.temperature || 0.7,
343
+ stream
344
+ };
345
+ }
346
+ buildGeminiRequest(messages) {
347
+ const contents = messages
348
+ .filter(m => m.role !== 'system')
349
+ .map(m => ({
350
+ role: m.role === 'assistant' ? 'model' : 'user',
351
+ parts: [{ text: m.content }]
352
+ }));
353
+ return {
354
+ contents,
355
+ generationConfig: {
356
+ temperature: this.config.temperature || 0.7,
357
+ maxOutputTokens: this.config.maxTokens || 4096
358
+ }
359
+ };
360
+ }
361
+ getApiKey() {
362
+ const provider = this.config.provider || 'siliconflow';
363
+ const envKeys = {
364
+ siliconflow: ['SILICONFLOW_API_KEY', 'OPENAI_API_KEY'],
365
+ minimax: ['MINIMAX_API_KEY', 'OPENAI_API_KEY'],
366
+ openai: ['OPENAI_API_KEY'],
367
+ anthropic: ['ANTHROPIC_API_KEY'],
368
+ ollama: [],
369
+ gemini: ['GEMINI_API_KEY'],
370
+ kimi: ['KIMI_API_KEY', 'MOONSHOT_API_KEY'],
371
+ deepseek: ['DEEPSEEK_API_KEY']
372
+ };
373
+ for (const key of envKeys[provider] || []) {
374
+ if (process.env[key])
375
+ return process.env[key];
376
+ }
377
+ return '';
378
+ }
379
+ getMockResponse(messages) {
380
+ const lastMessage = messages[messages.length - 1]?.content || '';
381
+ let response = 'Hello! I am Thatgfsj Code.\n\n';
382
+ if (lastMessage.toLowerCase().includes('hello') || lastMessage.toLowerCase().includes('hi')) {
383
+ response = 'Hi there! How can I help you today?';
384
+ }
385
+ else if (lastMessage.toLowerCase().includes('who are you')) {
386
+ response = 'I am Thatgfsj Code, an AI assistant built with Node.js.';
387
+ }
388
+ else {
389
+ response = `I understand you said: "${lastMessage.slice(0, 50)}..."\n\nThis is a streaming demo. Enable an API key for full AI capabilities.`;
390
+ }
391
+ return response;
392
+ }
393
+ }
394
+ //# sourceMappingURL=ai-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-engine.js","sourceRoot":"","sources":["../../src/core/ai-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * S12: CLI & Architecture
3
+ *
4
+ * Main entry point, CLI argument parsing, and module architecture overview.
5
+ */
6
+ export interface CLIOptions {
7
+ model?: string;
8
+ provider?: string;
9
+ prompt?: string;
10
+ noStream?: boolean;
11
+ verbose?: boolean;
12
+ hooks?: boolean;
13
+ permissionMode?: 'accept' | 'deny' | 'ask';
14
+ }
15
+ export declare function parseArgs(args: string[]): CLIOptions;
16
+ /**
17
+ * S12: Print architecture overview
18
+ */
19
+ export declare function printArchitecture(): void;
20
+ export declare function main(argv: string[]): Promise<void>;
21
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/core/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgBH,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;CAC5C;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAwCpD;AA4BD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAyBxC;AAID,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCxD"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * S12: CLI & Architecture
3
+ *
4
+ * Main entry point, CLI argument parsing, and module architecture overview.
5
+ */
6
+ import { AIEngine } from './ai-engine.js';
7
+ import { ConfigManager } from './config.js';
8
+ import { REPLLoop } from '../repl/loop.js';
9
+ import { ShellTool, FileTool, GitTool } from '../tools/index.js';
10
+ import { auditLogHook, getHookManager } from './hooks.js';
11
+ import { SystemPromptBuilder } from './system-prompt.js';
12
+ export function parseArgs(args) {
13
+ const options = {};
14
+ for (let i = 0; i < args.length; i++) {
15
+ const arg = args[i];
16
+ switch (arg) {
17
+ case '--model':
18
+ case '-m':
19
+ options.model = args[++i];
20
+ break;
21
+ case '--provider':
22
+ case '-p':
23
+ options.provider = args[++i];
24
+ break;
25
+ case '--prompt':
26
+ case '-c':
27
+ options.prompt = args[++i];
28
+ break;
29
+ case '--no-stream':
30
+ options.noStream = true;
31
+ break;
32
+ case '--verbose':
33
+ case '-v':
34
+ options.verbose = true;
35
+ break;
36
+ case '--hooks':
37
+ options.hooks = true;
38
+ break;
39
+ case '--permission':
40
+ options.permissionMode = args[++i] || 'ask';
41
+ break;
42
+ case '--help':
43
+ case '-h':
44
+ printHelp();
45
+ process.exit(0);
46
+ }
47
+ }
48
+ return options;
49
+ }
50
+ function printHelp() {
51
+ console.log(`
52
+ Thatgfsj Code - AI Coding Assistant
53
+
54
+ Usage: thatgfsj [options]
55
+
56
+ Options:
57
+ -m, --model <model> Set AI model
58
+ -p, --provider <provider> Set provider (siliconflow, minimax, openai, etc.)
59
+ -c, --prompt <text> Run single prompt and exit
60
+ --no-stream Disable streaming output
61
+ --hooks Enable built-in hooks (audit log, etc.)
62
+ --permission <mode> Set permission mode (accept, deny, ask)
63
+ -v, --verbose Verbose output
64
+ -h, --help Show this help
65
+
66
+ Examples:
67
+ thatgfsj Start REPL
68
+ thatgfsj -c "Hello" Run single prompt
69
+ thatgfsj --provider minimax --model MiniMax-M2.5 Use specific provider
70
+ thatgfsj --permission accept Accept all tool calls
71
+ `);
72
+ }
73
+ // ==================== Architecture ====================
74
+ /**
75
+ * S12: Print architecture overview
76
+ */
77
+ export function printArchitecture() {
78
+ console.log(`
79
+ Thatgfsj Code Architecture
80
+ ============================
81
+
82
+ Core:
83
+ AIEngine - Async generator agent loop (S01), multi-provider
84
+ ToolRegistry - Tool registration and execution (S02)
85
+ PermissionChecker - 6-stage permission pipeline (S03)
86
+ SystemPromptBuilder - Dynamic prompt construction (S04)
87
+ ContextCompactor - 3-tier context compression (S05)
88
+ SubagentManager - Parallel subagent execution (S06)
89
+ HookManager - Event-driven hooks (S08)
90
+ SkillsLoader - Skills discovery and catalog (S10)
91
+ StateManager - Ephemeral/Persistent/Session state (S11)
92
+
93
+ Tools:
94
+ ShellTool - Shell command execution
95
+ FileTool - File read/write/list/delete
96
+ GitTool - Git operations
97
+
98
+ Entry:
99
+ REPLLoop - Interactive REPL
100
+ CLI - Command-line mode
101
+ `);
102
+ }
103
+ // ==================== Main ====================
104
+ export async function main(argv) {
105
+ const options = parseArgs(argv.slice(2));
106
+ // Single prompt mode
107
+ if (options.prompt) {
108
+ const config = await ConfigManager.load();
109
+ if (options.provider)
110
+ config.provider = options.provider;
111
+ if (options.model)
112
+ config.model = options.model;
113
+ const ai = new AIEngine(config);
114
+ const tools = [new ShellTool(), new FileTool(), new GitTool()];
115
+ for (const tool of tools)
116
+ ai.registerTool(tool);
117
+ if (options.hooks) {
118
+ const hooks = getHookManager();
119
+ hooks.register('afterToolCall', auditLogHook);
120
+ ai.setHooks(hooks);
121
+ }
122
+ const promptBuilder = new SystemPromptBuilder({ tools, permissionMode: options.permissionMode });
123
+ const messages = [
124
+ { role: 'system', content: promptBuilder.build() },
125
+ { role: 'user', content: options.prompt }
126
+ ];
127
+ if (options.noStream) {
128
+ const response = await ai.chat(messages);
129
+ console.log(response.content);
130
+ }
131
+ else {
132
+ for await (const chunk of ai.chatStream(messages)) {
133
+ process.stdout.write(chunk);
134
+ }
135
+ console.log();
136
+ }
137
+ return;
138
+ }
139
+ // REPL mode
140
+ const repl = new REPLLoop();
141
+ await repl.start();
142
+ }
143
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/core/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Config Manager - Handles configuration loading and saving
3
+ * Supports multiple AI providers: MiniMax, SiliconFlow, OpenAI, Anthropic
4
+ *
5
+ * 0.2.3: Tolerates unknown / legacy provider names (e.g. `custom_openai`
6
+ * from 1.0.4-era configs) — keeps the user's provider and falls back to
7
+ * deriving a sensible baseUrl from `CUSTOM_BASE_URL` / `BASE_URL` env vars
8
+ * or from the provider id itself, instead of silently overwriting the
9
+ * provider field. Also refreshes default model to current SiliconFlow
10
+ * recommendation (Qwen2.5-72B-Instruct instead of 7B).
11
+ */
12
+ import { Config, AIConfig } from './types.js';
13
+ export declare class ConfigManager {
14
+ private configPath;
15
+ constructor();
16
+ /**
17
+ * Load configuration with environment variable support
18
+ */
19
+ static load(): Promise<Config>;
20
+ /**
21
+ * Load config from file and merge with environment variables
22
+ */
23
+ private loadConfig;
24
+ /**
25
+ * Resolve provider and API key from config or environment
26
+ *
27
+ * 0.2.3: tolerate unknown / legacy provider names (e.g. `custom_openai`).
28
+ * - If the provider is in `PROVIDERS`, use its baseUrl + envKeys.
29
+ * - Otherwise keep the user-specified provider id exactly and try to
30
+ * derive a baseUrl from `CUSTOM_BASE_URL` / `BASE_URL` env vars; if
31
+ * neither is set, fall back to the OpenAI-compatible default
32
+ * (https://api.openai.com/v1) so the request still goes through.
33
+ * No silent overwrite of `provider`.
34
+ * - When API key is missing for an unknown provider, we still keep the
35
+ * provider and surface a non-fatal warning.
36
+ */
37
+ private resolveProvider;
38
+ /**
39
+ * Get AIConfig for AIEngine
40
+ */
41
+ static getAIConfig(): Promise<AIConfig>;
42
+ /**
43
+ * Save configuration
44
+ */
45
+ save(config: Partial<Config>): Promise<void>;
46
+ /**
47
+ * Get config path
48
+ */
49
+ getPath(): string;
50
+ /**
51
+ * List available providers
52
+ */
53
+ static listProviders(): string;
54
+ }
55
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAE,MAAM,EAAa,QAAQ,EAAE,MAAM,YAAY,CAAC;AAWzD,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAS;;IAQ3B;;OAEG;WACU,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAKpC;;OAEG;IACH,OAAO,CAAC,UAAU;IAmBlB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,eAAe;IA4DvB;;OAEG;WACU,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC;IAY7C;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlD;;OAEG;IACH,OAAO,IAAI,MAAM;IAIjB;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,MAAM;CAK/B"}