snow-ai 0.3.36 → 0.3.37

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 (89) hide show
  1. package/dist/agents/codebaseIndexAgent.js +1 -0
  2. package/dist/agents/codebaseReviewAgent.d.ts +61 -0
  3. package/dist/agents/codebaseReviewAgent.js +301 -0
  4. package/dist/api/anthropic.js +1 -0
  5. package/dist/api/chat.js +1 -0
  6. package/dist/api/embedding.js +1 -0
  7. package/dist/api/gemini.js +2 -1
  8. package/dist/api/responses.js +1 -0
  9. package/dist/api/systemPrompt.d.ts +1 -5
  10. package/dist/api/systemPrompt.js +168 -100
  11. package/dist/app.js +14 -6
  12. package/dist/cli.js +1 -1
  13. package/dist/hooks/useCommandPanel.js +48 -46
  14. package/dist/hooks/useConversation.d.ts +2 -1
  15. package/dist/hooks/useConversation.js +110 -28
  16. package/dist/hooks/useGlobalExit.js +4 -2
  17. package/dist/hooks/useStreamingState.d.ts +9 -0
  18. package/dist/hooks/useStreamingState.js +3 -0
  19. package/dist/i18n/I18nContext.d.ts +14 -0
  20. package/dist/i18n/I18nContext.js +24 -0
  21. package/dist/i18n/index.d.ts +3 -0
  22. package/dist/i18n/index.js +2 -0
  23. package/dist/i18n/lang/en.d.ts +2 -0
  24. package/dist/i18n/lang/en.js +481 -0
  25. package/dist/i18n/lang/es.d.ts +2 -0
  26. package/dist/i18n/lang/es.js +481 -0
  27. package/dist/i18n/lang/ja.d.ts +2 -0
  28. package/dist/i18n/lang/ja.js +481 -0
  29. package/dist/i18n/lang/ko.d.ts +2 -0
  30. package/dist/i18n/lang/ko.js +481 -0
  31. package/dist/i18n/lang/zh-TW.d.ts +2 -0
  32. package/dist/i18n/lang/zh-TW.js +481 -0
  33. package/dist/i18n/lang/zh.d.ts +2 -0
  34. package/dist/i18n/lang/zh.js +481 -0
  35. package/dist/i18n/translations.d.ts +2 -0
  36. package/dist/i18n/translations.js +14 -0
  37. package/dist/i18n/types.d.ts +457 -0
  38. package/dist/i18n/types.js +1 -0
  39. package/dist/mcp/aceCodeSearch.d.ts +17 -48
  40. package/dist/mcp/aceCodeSearch.js +24 -56
  41. package/dist/mcp/codebaseSearch.d.ts +1 -1
  42. package/dist/mcp/codebaseSearch.js +159 -30
  43. package/dist/mcp/filesystem.d.ts +3 -80
  44. package/dist/mcp/filesystem.js +7 -92
  45. package/dist/mcp/subagent.d.ts +2 -1
  46. package/dist/mcp/subagent.js +54 -5
  47. package/dist/ui/components/ChatInput.js +23 -26
  48. package/dist/ui/components/CommandPanel.d.ts +1 -1
  49. package/dist/ui/components/CommandPanel.js +20 -13
  50. package/dist/ui/components/HelpPanel.js +47 -21
  51. package/dist/ui/components/Menu.js +6 -2
  52. package/dist/ui/components/MessageList.d.ts +6 -0
  53. package/dist/ui/components/MessageList.js +1 -1
  54. package/dist/ui/components/ToolConfirmation.d.ts +4 -1
  55. package/dist/ui/components/ToolConfirmation.js +28 -2
  56. package/dist/ui/components/ToolResultPreview.d.ts +2 -1
  57. package/dist/ui/components/ToolResultPreview.js +26 -22
  58. package/dist/ui/pages/ChatScreen.js +126 -49
  59. package/dist/ui/pages/CodeBaseConfigScreen.js +54 -30
  60. package/dist/ui/pages/ConfigScreen.js +102 -98
  61. package/dist/ui/pages/CustomHeadersScreen.js +75 -69
  62. package/dist/ui/pages/LanguageSettingsScreen.d.ts +7 -0
  63. package/dist/ui/pages/LanguageSettingsScreen.js +89 -0
  64. package/dist/ui/pages/ProxyConfigScreen.js +27 -23
  65. package/dist/ui/pages/SensitiveCommandConfigScreen.js +32 -25
  66. package/dist/ui/pages/SubAgentConfigScreen.js +88 -75
  67. package/dist/ui/pages/SystemPromptConfigScreen.js +31 -26
  68. package/dist/ui/pages/WelcomeScreen.js +40 -26
  69. package/dist/utils/codebaseConfig.d.ts +1 -5
  70. package/dist/utils/codebaseConfig.js +2 -10
  71. package/dist/utils/codebaseSearchEvents.d.ts +16 -0
  72. package/dist/utils/codebaseSearchEvents.js +13 -0
  73. package/dist/utils/commands/agent.js +2 -2
  74. package/dist/utils/commands/init.js +1 -1
  75. package/dist/utils/configManager.js +26 -5
  76. package/dist/utils/contextCompressor.js +1 -1
  77. package/dist/utils/languageConfig.d.ts +21 -0
  78. package/dist/utils/languageConfig.js +61 -0
  79. package/dist/utils/mcpToolsManager.js +0 -9
  80. package/dist/utils/notebookManager.js +11 -4
  81. package/dist/utils/sessionConverter.js +13 -3
  82. package/dist/utils/subAgentConfig.d.ts +10 -5
  83. package/dist/utils/subAgentConfig.js +112 -19
  84. package/dist/utils/subAgentExecutor.d.ts +9 -1
  85. package/dist/utils/subAgentExecutor.js +122 -9
  86. package/dist/utils/toolExecutor.d.ts +2 -1
  87. package/dist/utils/toolExecutor.js +1 -2
  88. package/dist/utils/usageLogger.js +18 -3
  89. package/package.json +1 -1
@@ -619,6 +619,7 @@ Object.defineProperty(CodebaseIndexAgent, "CODE_EXTENSIONS", {
619
619
  '.kt',
620
620
  '.scala',
621
621
  '.m',
622
+ '.md',
622
623
  '.mm',
623
624
  '.sh',
624
625
  '.bash',
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Codebase Review Agent Service
3
+ *
4
+ * Reviews codebase search results to filter out irrelevant items.
5
+ * Uses basicModel for efficient, low-cost relevance checking.
6
+ * Can also suggest better search keywords if results are not relevant.
7
+ */
8
+ export declare class CodebaseReviewAgent {
9
+ private modelName;
10
+ private requestMethod;
11
+ private initialized;
12
+ private readonly MAX_RETRIES;
13
+ /**
14
+ * Initialize the review agent with current configuration
15
+ */
16
+ private initialize;
17
+ /**
18
+ * Check if review agent is available
19
+ */
20
+ isAvailable(): Promise<boolean>;
21
+ /**
22
+ * Call the model with streaming API and assemble complete response
23
+ */
24
+ private callModel;
25
+ /**
26
+ * Try to parse JSON response with retry logic
27
+ */
28
+ private tryParseJSON;
29
+ /**
30
+ * Review search results with retry mechanism
31
+ */
32
+ private reviewWithRetry;
33
+ /**
34
+ * Sleep utility for retry backoff
35
+ */
36
+ private sleep;
37
+ /**
38
+ * Review search results and filter out irrelevant ones
39
+ * With retry mechanism and graceful degradation
40
+ *
41
+ * @param query - Original search query
42
+ * @param results - Search results to review
43
+ * @param abortSignal - Optional abort signal
44
+ * @returns Object with filtered results and optional suggestions
45
+ */
46
+ reviewResults(query: string, results: Array<{
47
+ rank: number;
48
+ filePath: string;
49
+ startLine: number;
50
+ endLine: number;
51
+ content: string;
52
+ similarityScore: string;
53
+ location: string;
54
+ }>, abortSignal?: AbortSignal): Promise<{
55
+ filteredResults: typeof results;
56
+ removedCount: number;
57
+ suggestions?: string[];
58
+ reviewFailed?: boolean;
59
+ }>;
60
+ }
61
+ export declare const codebaseReviewAgent: CodebaseReviewAgent;
@@ -0,0 +1,301 @@
1
+ import { getOpenAiConfig } from '../utils/apiConfig.js';
2
+ import { logger } from '../utils/logger.js';
3
+ import { createStreamingChatCompletion } from '../api/chat.js';
4
+ import { createStreamingResponse } from '../api/responses.js';
5
+ import { createStreamingGeminiCompletion } from '../api/gemini.js';
6
+ import { createStreamingAnthropicCompletion } from '../api/anthropic.js';
7
+ /**
8
+ * Codebase Review Agent Service
9
+ *
10
+ * Reviews codebase search results to filter out irrelevant items.
11
+ * Uses basicModel for efficient, low-cost relevance checking.
12
+ * Can also suggest better search keywords if results are not relevant.
13
+ */
14
+ export class CodebaseReviewAgent {
15
+ constructor() {
16
+ Object.defineProperty(this, "modelName", {
17
+ enumerable: true,
18
+ configurable: true,
19
+ writable: true,
20
+ value: ''
21
+ });
22
+ Object.defineProperty(this, "requestMethod", {
23
+ enumerable: true,
24
+ configurable: true,
25
+ writable: true,
26
+ value: 'chat'
27
+ });
28
+ Object.defineProperty(this, "initialized", {
29
+ enumerable: true,
30
+ configurable: true,
31
+ writable: true,
32
+ value: false
33
+ });
34
+ Object.defineProperty(this, "MAX_RETRIES", {
35
+ enumerable: true,
36
+ configurable: true,
37
+ writable: true,
38
+ value: 3
39
+ });
40
+ }
41
+ /**
42
+ * Initialize the review agent with current configuration
43
+ */
44
+ async initialize() {
45
+ try {
46
+ const config = getOpenAiConfig();
47
+ if (!config.basicModel) {
48
+ logger.warn('Codebase review agent: Basic model not configured, using advanced model as fallback');
49
+ if (!config.advancedModel) {
50
+ logger.warn('Codebase review agent: No model configured');
51
+ return false;
52
+ }
53
+ this.modelName = config.advancedModel;
54
+ }
55
+ else {
56
+ this.modelName = config.basicModel;
57
+ }
58
+ this.requestMethod = config.requestMethod;
59
+ this.initialized = true;
60
+ return true;
61
+ }
62
+ catch (error) {
63
+ logger.warn('Codebase review agent: Failed to initialize:', error);
64
+ return false;
65
+ }
66
+ }
67
+ /**
68
+ * Check if review agent is available
69
+ */
70
+ async isAvailable() {
71
+ if (!this.initialized) {
72
+ return await this.initialize();
73
+ }
74
+ return true;
75
+ }
76
+ /**
77
+ * Call the model with streaming API and assemble complete response
78
+ */
79
+ async callModel(messages, abortSignal) {
80
+ let streamGenerator;
81
+ switch (this.requestMethod) {
82
+ case 'anthropic':
83
+ streamGenerator = createStreamingAnthropicCompletion({
84
+ model: this.modelName,
85
+ messages,
86
+ includeBuiltinSystemPrompt: false,
87
+ disableThinking: true,
88
+ }, abortSignal);
89
+ break;
90
+ case 'gemini':
91
+ streamGenerator = createStreamingGeminiCompletion({
92
+ model: this.modelName,
93
+ messages,
94
+ includeBuiltinSystemPrompt: false,
95
+ }, abortSignal);
96
+ break;
97
+ case 'responses':
98
+ streamGenerator = createStreamingResponse({
99
+ model: this.modelName,
100
+ messages,
101
+ stream: true,
102
+ includeBuiltinSystemPrompt: false,
103
+ }, abortSignal);
104
+ break;
105
+ case 'chat':
106
+ default:
107
+ streamGenerator = createStreamingChatCompletion({
108
+ model: this.modelName,
109
+ messages,
110
+ stream: true,
111
+ includeBuiltinSystemPrompt: false,
112
+ }, abortSignal);
113
+ break;
114
+ }
115
+ let completeContent = '';
116
+ try {
117
+ for await (const chunk of streamGenerator) {
118
+ if (abortSignal?.aborted) {
119
+ throw new Error('Request aborted');
120
+ }
121
+ if (this.requestMethod === 'chat') {
122
+ if (chunk.choices && chunk.choices[0]?.delta?.content) {
123
+ completeContent += chunk.choices[0].delta.content;
124
+ }
125
+ }
126
+ else {
127
+ if (chunk.type === 'content' && chunk.content) {
128
+ completeContent += chunk.content;
129
+ }
130
+ }
131
+ }
132
+ }
133
+ catch (streamError) {
134
+ logger.error('Codebase review agent: Streaming error:', streamError);
135
+ throw streamError;
136
+ }
137
+ return completeContent;
138
+ }
139
+ /**
140
+ * Try to parse JSON response with retry logic
141
+ */
142
+ tryParseJSON(response) {
143
+ try {
144
+ // Extract JSON from markdown code blocks if present
145
+ let jsonStr = response.trim();
146
+ const jsonMatch = jsonStr.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
147
+ if (jsonMatch) {
148
+ jsonStr = jsonMatch[1].trim();
149
+ }
150
+ const parsed = JSON.parse(jsonStr);
151
+ // Validate structure
152
+ if (!Array.isArray(parsed.relevantIndices)) {
153
+ logger.warn('Codebase review agent: Invalid JSON structure - missing relevantIndices array');
154
+ return null;
155
+ }
156
+ return parsed;
157
+ }
158
+ catch (error) {
159
+ logger.warn('Codebase review agent: JSON parse error:', error);
160
+ return null;
161
+ }
162
+ }
163
+ /**
164
+ * Review search results with retry mechanism
165
+ */
166
+ async reviewWithRetry(query, results, abortSignal) {
167
+ const reviewPrompt = `You are a code search result reviewer. Your task is to analyze search results and determine which ones are truly relevant to the user's query.
168
+
169
+ Search Query: "${query}"
170
+
171
+ Search Results (${results.length} items):
172
+ ${results
173
+ .map((r, idx) => `\n[Result ${idx + 1}]
174
+ File: ${r.filePath}
175
+ Lines: ${r.startLine}-${r.endLine}
176
+ Similarity Score: ${r.similarityScore}%
177
+ Code:
178
+ \`\`\`
179
+ ${r.content}
180
+ \`\`\``)
181
+ .join('\n---')}
182
+
183
+ Your Tasks:
184
+ 1. Identify which results are RELEVANT to the search query
185
+ 2. Mark irrelevant results for removal
186
+ 3. If most results are irrelevant, suggest better search keywords
187
+
188
+ Output in JSON format:
189
+ {
190
+ "relevantIndices": [1, 3, 5],
191
+ "removedIndices": [2, 4],
192
+ "suggestions": ["keyword1", "keyword2"]
193
+ }
194
+
195
+ Guidelines:
196
+ - Be strict but fair: code doesn't need to match exactly, but should be semantically related
197
+ - Consider file paths, code content, and context
198
+ - If a result is marginally relevant, keep it
199
+ - Only suggest new keywords if >50% of results are irrelevant
200
+ - Return ONLY valid JSON, no other text or explanation`;
201
+ const messages = [
202
+ {
203
+ role: 'user',
204
+ content: reviewPrompt,
205
+ },
206
+ ];
207
+ // Retry loop
208
+ for (let attempt = 1; attempt <= this.MAX_RETRIES; attempt++) {
209
+ try {
210
+ logger.info(`Codebase review agent: Attempt ${attempt}/${this.MAX_RETRIES}`);
211
+ const response = await this.callModel(messages, abortSignal);
212
+ if (!response || response.trim().length === 0) {
213
+ logger.warn(`Codebase review agent: Empty response on attempt ${attempt}`);
214
+ if (attempt < this.MAX_RETRIES) {
215
+ await this.sleep(500 * attempt); // Exponential backoff
216
+ continue;
217
+ }
218
+ return null;
219
+ }
220
+ // Try to parse JSON
221
+ const parsed = this.tryParseJSON(response);
222
+ if (parsed) {
223
+ logger.info(`Codebase review agent: Successfully parsed on attempt ${attempt}`);
224
+ return { parsed, attempt };
225
+ }
226
+ // If parse failed and we have retries left
227
+ if (attempt < this.MAX_RETRIES) {
228
+ logger.warn(`Codebase review agent: Parse failed on attempt ${attempt}, retrying...`);
229
+ await this.sleep(500 * attempt); // Exponential backoff
230
+ continue;
231
+ }
232
+ return null;
233
+ }
234
+ catch (error) {
235
+ logger.error(`Codebase review agent: Error on attempt ${attempt}:`, error);
236
+ if (attempt < this.MAX_RETRIES) {
237
+ await this.sleep(500 * attempt); // Exponential backoff
238
+ continue;
239
+ }
240
+ return null;
241
+ }
242
+ }
243
+ return null;
244
+ }
245
+ /**
246
+ * Sleep utility for retry backoff
247
+ */
248
+ sleep(ms) {
249
+ return new Promise(resolve => setTimeout(resolve, ms));
250
+ }
251
+ /**
252
+ * Review search results and filter out irrelevant ones
253
+ * With retry mechanism and graceful degradation
254
+ *
255
+ * @param query - Original search query
256
+ * @param results - Search results to review
257
+ * @param abortSignal - Optional abort signal
258
+ * @returns Object with filtered results and optional suggestions
259
+ */
260
+ async reviewResults(query, results, abortSignal) {
261
+ const available = await this.isAvailable();
262
+ if (!available) {
263
+ logger.warn('Codebase review agent: Not available, returning original results');
264
+ return {
265
+ filteredResults: results,
266
+ removedCount: 0,
267
+ reviewFailed: true,
268
+ };
269
+ }
270
+ // Attempt review with retry
271
+ const reviewResult = await this.reviewWithRetry(query, results, abortSignal);
272
+ // If all retries failed, gracefully degrade
273
+ if (!reviewResult) {
274
+ logger.warn('Codebase review agent: All retry attempts failed, returning original results');
275
+ return {
276
+ filteredResults: results,
277
+ removedCount: 0,
278
+ reviewFailed: true,
279
+ };
280
+ }
281
+ // Success - filter results
282
+ const { parsed, attempt } = reviewResult;
283
+ const filteredResults = results.filter((_, idx) => parsed.relevantIndices.includes(idx + 1));
284
+ const removedCount = results.length - filteredResults.length;
285
+ logger.info('Codebase review agent: Review completed', {
286
+ originalCount: results.length,
287
+ filteredCount: filteredResults.length,
288
+ removedCount,
289
+ attempts: attempt,
290
+ hasSuggestions: !!parsed.suggestions?.length,
291
+ });
292
+ return {
293
+ filteredResults,
294
+ removedCount,
295
+ suggestions: parsed.suggestions || undefined,
296
+ reviewFailed: false,
297
+ };
298
+ }
299
+ }
300
+ // Export singleton instance
301
+ export const codebaseReviewAgent = new CodebaseReviewAgent();
@@ -312,6 +312,7 @@ export async function* createStreamingAnthropicCompletion(options, abortSignal,
312
312
  'x-api-key': config.apiKey,
313
313
  Authorization: `Bearer ${config.apiKey}`,
314
314
  'anthropic-version': '2023-06-01',
315
+ 'x-snow': 'true',
315
316
  ...config.customHeaders,
316
317
  };
317
318
  // Add beta parameter if configured
package/dist/api/chat.js CHANGED
@@ -186,6 +186,7 @@ export async function* createStreamingChatCompletion(options, abortSignal, onRet
186
186
  headers: {
187
187
  'Content-Type': 'application/json',
188
188
  Authorization: `Bearer ${config.apiKey}`,
189
+ 'x-snow': 'true',
189
190
  ...config.customHeaders,
190
191
  },
191
192
  body: JSON.stringify(requestBody),
@@ -44,6 +44,7 @@ export async function createEmbeddings(options) {
44
44
  // Build headers - only include Authorization if API key is provided
45
45
  const headers = {
46
46
  'Content-Type': 'application/json',
47
+ 'x-snow': 'true',
47
48
  };
48
49
  if (apiKey) {
49
50
  headers['Authorization'] = `Bearer ${apiKey}`;
@@ -255,7 +255,8 @@ export async function* createStreamingGeminiCompletion(options, abortSignal, onR
255
255
  method: 'POST',
256
256
  headers: {
257
257
  'Content-Type': 'application/json',
258
- 'Authorization': `Bearer ${config.apiKey}`,
258
+ Authorization: `Bearer ${config.apiKey}`,
259
+ 'x-snow': 'true',
259
260
  ...config.customHeaders,
260
261
  },
261
262
  body: JSON.stringify(requestBody),
@@ -275,6 +275,7 @@ export async function* createStreamingResponse(options, abortSignal, onRetry) {
275
275
  headers: {
276
276
  'Content-Type': 'application/json',
277
277
  Authorization: `Bearer ${config.apiKey}`,
278
+ 'x-snow': 'true',
278
279
  ...config.customHeaders,
279
280
  },
280
281
  body: JSON.stringify(requestPayload),
@@ -1,8 +1,4 @@
1
1
  /**
2
2
  * System prompt configuration for Snow AI CLI
3
3
  */
4
- export declare function getSystemPrompt(tools?: Array<{
5
- function: {
6
- name: string;
7
- };
8
- }>): string;
4
+ export declare function getSystemPrompt(): string;