snow-ai 0.2.23 → 0.2.25

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 (43) hide show
  1. package/dist/agents/compactAgent.d.ts +55 -0
  2. package/dist/agents/compactAgent.js +301 -0
  3. package/dist/api/chat.d.ts +0 -8
  4. package/dist/api/chat.js +1 -144
  5. package/dist/api/responses.d.ts +0 -11
  6. package/dist/api/responses.js +1 -189
  7. package/dist/api/systemPrompt.d.ts +1 -1
  8. package/dist/api/systemPrompt.js +80 -206
  9. package/dist/app.d.ts +2 -1
  10. package/dist/app.js +11 -13
  11. package/dist/cli.js +23 -3
  12. package/dist/hooks/useConversation.js +51 -7
  13. package/dist/hooks/useGlobalNavigation.d.ts +1 -1
  14. package/dist/hooks/useKeyboardInput.js +14 -8
  15. package/dist/mcp/filesystem.d.ts +49 -6
  16. package/dist/mcp/filesystem.js +243 -86
  17. package/dist/mcp/websearch.d.ts +118 -0
  18. package/dist/mcp/websearch.js +451 -0
  19. package/dist/ui/components/ToolResultPreview.js +60 -1
  20. package/dist/ui/pages/ChatScreen.d.ts +4 -2
  21. package/dist/ui/pages/ChatScreen.js +62 -14
  22. package/dist/ui/pages/{ApiConfigScreen.d.ts → ConfigScreen.d.ts} +1 -1
  23. package/dist/ui/pages/ConfigScreen.js +549 -0
  24. package/dist/ui/pages/{ModelConfigScreen.d.ts → ProxyConfigScreen.d.ts} +1 -1
  25. package/dist/ui/pages/ProxyConfigScreen.js +143 -0
  26. package/dist/ui/pages/WelcomeScreen.js +15 -15
  27. package/dist/utils/apiConfig.d.ts +8 -2
  28. package/dist/utils/apiConfig.js +21 -0
  29. package/dist/utils/commandExecutor.d.ts +1 -1
  30. package/dist/utils/contextCompressor.js +363 -49
  31. package/dist/utils/mcpToolsManager.d.ts +1 -1
  32. package/dist/utils/mcpToolsManager.js +106 -6
  33. package/dist/utils/resourceMonitor.d.ts +65 -0
  34. package/dist/utils/resourceMonitor.js +175 -0
  35. package/dist/utils/retryUtils.js +6 -0
  36. package/dist/utils/sessionManager.d.ts +1 -0
  37. package/dist/utils/sessionManager.js +10 -0
  38. package/dist/utils/textBuffer.js +7 -2
  39. package/dist/utils/toolExecutor.d.ts +2 -2
  40. package/dist/utils/toolExecutor.js +4 -4
  41. package/package.json +5 -1
  42. package/dist/ui/pages/ApiConfigScreen.js +0 -161
  43. package/dist/ui/pages/ModelConfigScreen.js +0 -467
@@ -1,467 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { Box, Text, useInput } from 'ink';
3
- import Gradient from 'ink-gradient';
4
- import { Select, Alert } from '@inkjs/ui';
5
- import { fetchAvailableModels, filterModels } from '../../api/models.js';
6
- import { getOpenAiConfig, updateOpenAiConfig, } from '../../utils/apiConfig.js';
7
- export default function ModelConfigScreen({ onBack, onSave, inlineMode = false }) {
8
- const [advancedModel, setAdvancedModel] = useState('');
9
- const [basicModel, setBasicModel] = useState('');
10
- const [maxContextTokens, setMaxContextTokens] = useState(4000);
11
- const [maxTokens, setMaxTokens] = useState(4096);
12
- const [compactBaseUrl, setCompactBaseUrl] = useState('');
13
- const [compactApiKey, setCompactApiKey] = useState('');
14
- const [compactModelName, setCompactModelName] = useState('');
15
- const [currentField, setCurrentField] = useState('advancedModel');
16
- const [isEditing, setIsEditing] = useState(false);
17
- const [models, setModels] = useState([]);
18
- const [loading, setLoading] = useState(false);
19
- const [baseUrlMissing, setBaseUrlMissing] = useState(false);
20
- const [searchTerm, setSearchTerm] = useState('');
21
- const [manualInputMode, setManualInputMode] = useState(false);
22
- const [manualInputValue, setManualInputValue] = useState('');
23
- useEffect(() => {
24
- const config = getOpenAiConfig();
25
- setAdvancedModel(config.advancedModel || '');
26
- setBasicModel(config.basicModel || '');
27
- setMaxContextTokens(config.maxContextTokens || 4000);
28
- setMaxTokens(config.maxTokens || 4096);
29
- setCompactBaseUrl(config.compactModel?.baseUrl || '');
30
- setCompactApiKey(config.compactModel?.apiKey || '');
31
- setCompactModelName(config.compactModel?.modelName || '');
32
- if (!config.baseUrl) {
33
- setBaseUrlMissing(true);
34
- return;
35
- }
36
- }, []);
37
- const loadModels = async () => {
38
- setLoading(true);
39
- try {
40
- const fetchedModels = await fetchAvailableModels();
41
- setModels(fetchedModels);
42
- }
43
- catch (err) {
44
- // 加载失败时抛出错误,由调用方处理
45
- throw err;
46
- }
47
- finally {
48
- setLoading(false);
49
- }
50
- };
51
- const getCurrentOptions = () => {
52
- const filteredModels = filterModels(models, searchTerm);
53
- const modelOptions = filteredModels.map(model => ({
54
- label: model.id,
55
- value: model.id,
56
- }));
57
- // 添加手动输入选项
58
- return [
59
- { label: 'Manual Input (Enter model name)', value: '__MANUAL_INPUT__' },
60
- ...modelOptions,
61
- ];
62
- };
63
- const getCurrentValue = () => {
64
- if (currentField === 'advancedModel')
65
- return advancedModel;
66
- if (currentField === 'basicModel')
67
- return basicModel;
68
- if (currentField === 'maxContextTokens')
69
- return maxContextTokens.toString();
70
- if (currentField === 'maxTokens')
71
- return maxTokens.toString();
72
- if (currentField === 'compactBaseUrl')
73
- return compactBaseUrl;
74
- if (currentField === 'compactApiKey')
75
- return compactApiKey;
76
- if (currentField === 'compactModelName')
77
- return compactModelName;
78
- return '';
79
- };
80
- const handleModelChange = (value) => {
81
- // 如果选择了手动输入选项
82
- if (value === '__MANUAL_INPUT__') {
83
- setManualInputMode(true);
84
- setManualInputValue('');
85
- return;
86
- }
87
- if (currentField === 'advancedModel') {
88
- setAdvancedModel(value);
89
- }
90
- else if (currentField === 'basicModel') {
91
- setBasicModel(value);
92
- }
93
- else if (currentField === 'maxContextTokens') {
94
- const numValue = parseInt(value, 10);
95
- if (!isNaN(numValue) && numValue > 0) {
96
- setMaxContextTokens(numValue);
97
- }
98
- }
99
- else if (currentField === 'maxTokens') {
100
- const numValue = parseInt(value, 10);
101
- if (!isNaN(numValue) && numValue > 0) {
102
- setMaxTokens(numValue);
103
- }
104
- }
105
- setIsEditing(false);
106
- setSearchTerm(''); // Reset search when selection is made
107
- };
108
- useInput((input, key) => {
109
- if (baseUrlMissing) {
110
- if (key.escape) {
111
- onBack();
112
- }
113
- return;
114
- }
115
- // 处理手动输入模式
116
- if (manualInputMode) {
117
- if (key.return) {
118
- // 确认输入
119
- if (manualInputValue.trim()) {
120
- if (currentField === 'advancedModel') {
121
- setAdvancedModel(manualInputValue.trim());
122
- }
123
- else if (currentField === 'basicModel') {
124
- setBasicModel(manualInputValue.trim());
125
- }
126
- }
127
- setManualInputMode(false);
128
- setManualInputValue('');
129
- setIsEditing(false);
130
- setSearchTerm('');
131
- }
132
- else if (key.escape) {
133
- // 取消输入
134
- setManualInputMode(false);
135
- setManualInputValue('');
136
- }
137
- else if (key.backspace || key.delete) {
138
- setManualInputValue(prev => prev.slice(0, -1));
139
- }
140
- else if (input && input.match(/[a-zA-Z0-9-_./:]/)) {
141
- setManualInputValue(prev => prev + input);
142
- }
143
- return;
144
- }
145
- // Don't handle input when Select component is active
146
- if (isEditing) {
147
- if (currentField === 'maxContextTokens') {
148
- // Handle numeric input for maxContextTokens
149
- if (input && input.match(/[0-9]/)) {
150
- const newValue = parseInt(maxContextTokens.toString() + input, 10);
151
- if (!isNaN(newValue)) {
152
- setMaxContextTokens(newValue);
153
- }
154
- }
155
- else if (key.backspace || key.delete) {
156
- const currentStr = maxContextTokens.toString();
157
- const newStr = currentStr.slice(0, -1);
158
- const newValue = parseInt(newStr, 10);
159
- if (!isNaN(newValue)) {
160
- setMaxContextTokens(newValue);
161
- }
162
- else {
163
- setMaxContextTokens(0);
164
- }
165
- }
166
- else if (key.return) {
167
- // Save value, but enforce minimum of 4000
168
- const finalValue = maxContextTokens < 4000 ? 4000 : maxContextTokens;
169
- setMaxContextTokens(finalValue);
170
- setIsEditing(false);
171
- }
172
- }
173
- else if (currentField === 'maxTokens') {
174
- // Handle numeric input for maxTokens
175
- if (input && input.match(/[0-9]/)) {
176
- const newValue = parseInt(maxTokens.toString() + input, 10);
177
- if (!isNaN(newValue)) {
178
- setMaxTokens(newValue);
179
- }
180
- }
181
- else if (key.backspace || key.delete) {
182
- const currentStr = maxTokens.toString();
183
- const newStr = currentStr.slice(0, -1);
184
- const newValue = parseInt(newStr, 10);
185
- if (!isNaN(newValue)) {
186
- setMaxTokens(newValue);
187
- }
188
- else {
189
- setMaxTokens(0);
190
- }
191
- }
192
- else if (key.return) {
193
- // Save value, but enforce minimum of 100
194
- const finalValue = maxTokens < 100 ? 100 : maxTokens;
195
- setMaxTokens(finalValue);
196
- setIsEditing(false);
197
- }
198
- }
199
- else if (currentField === 'compactBaseUrl' || currentField === 'compactApiKey' || currentField === 'compactModelName') {
200
- // Handle text input for compact model fields
201
- if (key.return) {
202
- setIsEditing(false);
203
- }
204
- else if (key.backspace || key.delete) {
205
- if (currentField === 'compactBaseUrl') {
206
- setCompactBaseUrl(prev => prev.slice(0, -1));
207
- }
208
- else if (currentField === 'compactApiKey') {
209
- setCompactApiKey(prev => prev.slice(0, -1));
210
- }
211
- else if (currentField === 'compactModelName') {
212
- setCompactModelName(prev => prev.slice(0, -1));
213
- }
214
- }
215
- else if (input && input.match(/[a-zA-Z0-9-_./:]/)) {
216
- if (currentField === 'compactBaseUrl') {
217
- setCompactBaseUrl(prev => prev + input);
218
- }
219
- else if (currentField === 'compactApiKey') {
220
- setCompactApiKey(prev => prev + input);
221
- }
222
- else if (currentField === 'compactModelName') {
223
- setCompactModelName(prev => prev + input);
224
- }
225
- }
226
- }
227
- else {
228
- // Allow typing to filter in edit mode for model selection
229
- if (input && input.match(/[a-zA-Z0-9-_.]/)) {
230
- setSearchTerm(prev => prev + input);
231
- }
232
- else if (key.backspace || key.delete) {
233
- setSearchTerm(prev => prev.slice(0, -1));
234
- }
235
- }
236
- return;
237
- }
238
- // Handle save/exit globally
239
- if (input === 's' && (key.ctrl || key.meta)) {
240
- const config = {
241
- advancedModel,
242
- basicModel,
243
- maxContextTokens,
244
- maxTokens,
245
- };
246
- // 只有当所有字段都填写时才保存 compactModel
247
- if (compactBaseUrl && compactApiKey && compactModelName) {
248
- config.compactModel = {
249
- baseUrl: compactBaseUrl,
250
- apiKey: compactApiKey,
251
- modelName: compactModelName,
252
- };
253
- }
254
- updateOpenAiConfig(config);
255
- onSave();
256
- }
257
- else if (key.escape) {
258
- const config = {
259
- advancedModel,
260
- basicModel,
261
- maxContextTokens,
262
- maxTokens,
263
- };
264
- // 只有当所有字段都填写时才保存 compactModel
265
- if (compactBaseUrl && compactApiKey && compactModelName) {
266
- config.compactModel = {
267
- baseUrl: compactBaseUrl,
268
- apiKey: compactApiKey,
269
- modelName: compactModelName,
270
- };
271
- }
272
- updateOpenAiConfig(config);
273
- onBack();
274
- }
275
- else if (key.return) {
276
- // Load models first for model fields, or enter edit mode directly for maxContextTokens/maxTokens and compact fields
277
- setSearchTerm(''); // Reset search when entering edit mode
278
- const isCompactField = currentField === 'compactBaseUrl' || currentField === 'compactApiKey' || currentField === 'compactModelName';
279
- if (currentField === 'maxContextTokens' || currentField === 'maxTokens' || isCompactField) {
280
- setIsEditing(true);
281
- }
282
- else {
283
- loadModels().then(() => {
284
- setIsEditing(true);
285
- }).catch(() => {
286
- // 如果加载模型失败,直接进入手动输入模式
287
- setManualInputMode(true);
288
- setManualInputValue(getCurrentValue());
289
- });
290
- }
291
- }
292
- else if (input === 'm') {
293
- // 快捷键:按 'm' 直接进入手动输入模式
294
- const isCompactField = currentField === 'compactBaseUrl' || currentField === 'compactApiKey' || currentField === 'compactModelName';
295
- if (currentField !== 'maxContextTokens' && currentField !== 'maxTokens' && !isCompactField) {
296
- setManualInputMode(true);
297
- setManualInputValue(getCurrentValue());
298
- }
299
- }
300
- else if (key.upArrow) {
301
- if (currentField === 'basicModel') {
302
- setCurrentField('advancedModel');
303
- }
304
- else if (currentField === 'maxContextTokens') {
305
- setCurrentField('basicModel');
306
- }
307
- else if (currentField === 'maxTokens') {
308
- setCurrentField('maxContextTokens');
309
- }
310
- else if (currentField === 'compactBaseUrl') {
311
- setCurrentField('maxTokens');
312
- }
313
- else if (currentField === 'compactApiKey') {
314
- setCurrentField('compactBaseUrl');
315
- }
316
- else if (currentField === 'compactModelName') {
317
- setCurrentField('compactApiKey');
318
- }
319
- }
320
- else if (key.downArrow) {
321
- if (currentField === 'advancedModel') {
322
- setCurrentField('basicModel');
323
- }
324
- else if (currentField === 'basicModel') {
325
- setCurrentField('maxContextTokens');
326
- }
327
- else if (currentField === 'maxContextTokens') {
328
- setCurrentField('maxTokens');
329
- }
330
- else if (currentField === 'maxTokens') {
331
- setCurrentField('compactBaseUrl');
332
- }
333
- else if (currentField === 'compactBaseUrl') {
334
- setCurrentField('compactApiKey');
335
- }
336
- else if (currentField === 'compactApiKey') {
337
- setCurrentField('compactModelName');
338
- }
339
- }
340
- });
341
- if (baseUrlMissing) {
342
- return (React.createElement(Box, { flexDirection: "column", padding: 1 },
343
- !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: "cyan", paddingX: 1, paddingY: 0 },
344
- React.createElement(Box, { flexDirection: "column" },
345
- React.createElement(Gradient, { name: 'rainbow' }, "Model Configuration"),
346
- React.createElement(Text, { color: "gray", dimColor: true }, "Configure AI models for different tasks")))),
347
- React.createElement(Box, { marginBottom: 1 },
348
- React.createElement(Alert, { variant: "error" }, "Base URL not configured. Please configure API settings first before setting up models.")),
349
- React.createElement(Box, { flexDirection: "column" },
350
- React.createElement(Alert, { variant: "info" }, "Press Esc to return to main menu"))));
351
- }
352
- if (loading) {
353
- return (React.createElement(Box, { flexDirection: "column", padding: 1 }, !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", paddingX: 1, paddingY: 0 },
354
- React.createElement(Box, { flexDirection: "column" },
355
- React.createElement(Gradient, { name: "rainbow" }, "Model Configuration"),
356
- React.createElement(Text, { color: "gray", dimColor: true }, "Loading available models..."))))));
357
- }
358
- // 手动输入模式的界面
359
- if (manualInputMode) {
360
- return (React.createElement(Box, { flexDirection: "column", padding: 1 },
361
- !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: "cyan", paddingX: 1, paddingY: 0 },
362
- React.createElement(Box, { flexDirection: "column" },
363
- React.createElement(Gradient, { name: 'rainbow' }, "Manual Input Model"),
364
- React.createElement(Text, { color: "gray", dimColor: true }, "Enter model name manually")))),
365
- React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
366
- React.createElement(Text, { color: "cyan" },
367
- currentField === 'advancedModel' ? 'Advanced Model' : 'Basic Model',
368
- ":"),
369
- React.createElement(Box, { marginLeft: 2 },
370
- React.createElement(Text, { color: "green" },
371
- `> ${manualInputValue}`,
372
- React.createElement(Text, { color: "white" }, "_")))),
373
- React.createElement(Box, { flexDirection: "column" },
374
- React.createElement(Alert, { variant: "info" }, "Type model name (e.g., gpt-4o, claude-3-5-sonnet-20241022)"),
375
- React.createElement(Alert, { variant: "info" }, "Press Enter to confirm, Esc to cancel"))));
376
- }
377
- return (React.createElement(Box, { flexDirection: "column", padding: 1 },
378
- !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: "cyan", paddingX: 1, paddingY: 0 },
379
- React.createElement(Box, { flexDirection: "column" },
380
- React.createElement(Gradient, { name: 'rainbow' }, "Model Configuration"),
381
- React.createElement(Text, { color: "gray", dimColor: true }, "Configure AI models for different tasks")))),
382
- React.createElement(Box, { flexDirection: "column" },
383
- React.createElement(Box, null,
384
- React.createElement(Box, { flexDirection: "column" },
385
- React.createElement(Text, { color: currentField === 'advancedModel' ? 'green' : 'white' },
386
- currentField === 'advancedModel' ? '❯ ' : ' ',
387
- "Advanced Model (Main Work):"),
388
- currentField === 'advancedModel' && isEditing && (React.createElement(Box, { marginLeft: 3 }, loading ? (React.createElement(Text, { color: "yellow" }, "Loading models...")) : (React.createElement(Box, { flexDirection: "column" },
389
- searchTerm && (React.createElement(Text, { color: "cyan" },
390
- "Filter: ",
391
- searchTerm)),
392
- React.createElement(Select, { options: getCurrentOptions(), defaultValue: getCurrentValue(), onChange: handleModelChange }))))),
393
- (!isEditing || currentField !== 'advancedModel') && (React.createElement(Box, { marginLeft: 3 },
394
- React.createElement(Text, { color: "gray" }, advancedModel || 'Not set'))))),
395
- React.createElement(Box, null,
396
- React.createElement(Box, { flexDirection: "column" },
397
- React.createElement(Text, { color: currentField === 'basicModel' ? 'green' : 'white' },
398
- currentField === 'basicModel' ? '❯ ' : ' ',
399
- "Basic Model (Summary & Analysis):"),
400
- currentField === 'basicModel' && isEditing && (React.createElement(Box, { marginLeft: 3 }, loading ? (React.createElement(Text, { color: "yellow" }, "Loading models...")) : (React.createElement(Box, { flexDirection: "column" },
401
- searchTerm && (React.createElement(Text, { color: "cyan" },
402
- "Filter: ",
403
- searchTerm)),
404
- React.createElement(Select, { options: getCurrentOptions(), defaultValue: getCurrentValue(), onChange: handleModelChange }))))),
405
- (!isEditing || currentField !== 'basicModel') && (React.createElement(Box, { marginLeft: 3 },
406
- React.createElement(Text, { color: "gray" }, basicModel || 'Not set'))))),
407
- React.createElement(Box, null,
408
- React.createElement(Box, { flexDirection: "column" },
409
- React.createElement(Text, { color: currentField === 'maxContextTokens' ? 'green' : 'white' },
410
- currentField === 'maxContextTokens' ? '❯ ' : ' ',
411
- "Max Context Tokens (Auto-compress when reached):"),
412
- currentField === 'maxContextTokens' && isEditing && (React.createElement(Box, { marginLeft: 3 },
413
- React.createElement(Text, { color: "cyan" },
414
- "Enter value: ",
415
- maxContextTokens))),
416
- (!isEditing || currentField !== 'maxContextTokens') && (React.createElement(Box, { marginLeft: 3 },
417
- React.createElement(Text, { color: "gray" }, maxContextTokens))))),
418
- React.createElement(Box, null,
419
- React.createElement(Box, { flexDirection: "column" },
420
- React.createElement(Text, { color: currentField === 'maxTokens' ? 'green' : 'white' },
421
- currentField === 'maxTokens' ? '❯ ' : ' ',
422
- "Max Tokens (Max tokens for single response):"),
423
- currentField === 'maxTokens' && isEditing && (React.createElement(Box, { marginLeft: 3 },
424
- React.createElement(Text, { color: "cyan" },
425
- "Enter value: ",
426
- maxTokens))),
427
- (!isEditing || currentField !== 'maxTokens') && (React.createElement(Box, { marginLeft: 3 },
428
- React.createElement(Text, { color: "gray" }, maxTokens))))),
429
- React.createElement(Box, { marginTop: 1 },
430
- React.createElement(Text, { color: "cyan", bold: true }, "Compact Model (Context Compression):")),
431
- React.createElement(Box, null,
432
- React.createElement(Box, { flexDirection: "column" },
433
- React.createElement(Text, { color: currentField === 'compactBaseUrl' ? 'green' : 'white' },
434
- currentField === 'compactBaseUrl' ? '❯ ' : ' ',
435
- "Base URL:"),
436
- currentField === 'compactBaseUrl' && isEditing && (React.createElement(Box, { marginLeft: 3 },
437
- React.createElement(Text, { color: "cyan" },
438
- compactBaseUrl,
439
- React.createElement(Text, { color: "white" }, "_")))),
440
- (!isEditing || currentField !== 'compactBaseUrl') && (React.createElement(Box, { marginLeft: 3 },
441
- React.createElement(Text, { color: "gray" }, compactBaseUrl || 'Not set'))))),
442
- React.createElement(Box, null,
443
- React.createElement(Box, { flexDirection: "column" },
444
- React.createElement(Text, { color: currentField === 'compactApiKey' ? 'green' : 'white' },
445
- currentField === 'compactApiKey' ? '❯ ' : ' ',
446
- "API Key:"),
447
- currentField === 'compactApiKey' && isEditing && (React.createElement(Box, { marginLeft: 3 },
448
- React.createElement(Text, { color: "cyan" },
449
- compactApiKey.replace(/./g, '*'),
450
- React.createElement(Text, { color: "white" }, "_")))),
451
- (!isEditing || currentField !== 'compactApiKey') && (React.createElement(Box, { marginLeft: 3 },
452
- React.createElement(Text, { color: "gray" }, compactApiKey ? compactApiKey.replace(/./g, '*') : 'Not set'))))),
453
- React.createElement(Box, null,
454
- React.createElement(Box, { flexDirection: "column" },
455
- React.createElement(Text, { color: currentField === 'compactModelName' ? 'green' : 'white' },
456
- currentField === 'compactModelName' ? '❯ ' : ' ',
457
- "Model Name:"),
458
- currentField === 'compactModelName' && isEditing && (React.createElement(Box, { marginLeft: 3 },
459
- React.createElement(Text, { color: "cyan" },
460
- compactModelName,
461
- React.createElement(Text, { color: "white" }, "_")))),
462
- (!isEditing || currentField !== 'compactModelName') && (React.createElement(Box, { marginLeft: 3 },
463
- React.createElement(Text, { color: "gray" }, compactModelName || 'Not set')))))),
464
- React.createElement(Box, { flexDirection: "column", marginTop: 1 }, isEditing ? (React.createElement(React.Fragment, null,
465
- React.createElement(Alert, { variant: "info" }, "Editing mode: Type to filter models, \u2191\u2193 to select, Enter to confirm"))) : (React.createElement(React.Fragment, null,
466
- React.createElement(Alert, { variant: "info" }, "Use \u2191\u2193 to navigate, Enter to edit, M for manual input, Ctrl+S or Esc to save"))))));
467
- }