snow-ai 0.3.14 → 0.3.16
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.
- package/dist/api/systemPrompt.js +45 -1
- package/dist/hooks/useClipboard.js +12 -8
- package/dist/hooks/useCommandHandler.d.ts +0 -1
- package/dist/hooks/useCommandHandler.js +0 -6
- package/dist/hooks/useConversation.d.ts +7 -2
- package/dist/hooks/useConversation.js +13 -8
- package/dist/hooks/useHistoryNavigation.d.ts +10 -1
- package/dist/hooks/useHistoryNavigation.js +4 -5
- package/dist/hooks/useSnapshotState.d.ts +10 -0
- package/dist/ui/components/ChatInput.d.ts +8 -1
- package/dist/ui/components/ChatInput.js +95 -20
- package/dist/ui/components/MessageList.d.ts +0 -5
- package/dist/ui/components/MessageList.js +1 -14
- package/dist/ui/components/PendingMessages.d.ts +8 -1
- package/dist/ui/components/PendingMessages.js +14 -6
- package/dist/ui/pages/ChatScreen.js +31 -41
- package/dist/ui/pages/HeadlessModeScreen.js +2 -11
- package/dist/ui/pages/SubAgentConfigScreen.js +44 -3
- package/dist/ui/pages/SubAgentListScreen.js +17 -2
- package/dist/utils/chatExporter.js +0 -8
- package/dist/utils/commands/home.js +11 -2
- package/dist/utils/fileUtils.d.ts +1 -13
- package/dist/utils/fileUtils.js +1 -57
- package/dist/utils/mcpToolsManager.js +6 -2
- package/dist/utils/textBuffer.d.ts +15 -8
- package/dist/utils/textBuffer.js +56 -38
- package/package.json +1 -1
package/dist/utils/textBuffer.js
CHANGED
|
@@ -35,30 +35,24 @@ export class TextBuffer {
|
|
|
35
35
|
writable: true,
|
|
36
36
|
value: void 0
|
|
37
37
|
});
|
|
38
|
-
Object.defineProperty(this, "
|
|
38
|
+
Object.defineProperty(this, "placeholderStorage", {
|
|
39
39
|
enumerable: true,
|
|
40
40
|
configurable: true,
|
|
41
41
|
writable: true,
|
|
42
42
|
value: new Map()
|
|
43
|
-
});
|
|
44
|
-
Object.defineProperty(this, "
|
|
43
|
+
}); // 统一的占位符存储
|
|
44
|
+
Object.defineProperty(this, "textPlaceholderCounter", {
|
|
45
45
|
enumerable: true,
|
|
46
46
|
configurable: true,
|
|
47
47
|
writable: true,
|
|
48
48
|
value: 0
|
|
49
|
-
});
|
|
50
|
-
Object.defineProperty(this, "
|
|
51
|
-
enumerable: true,
|
|
52
|
-
configurable: true,
|
|
53
|
-
writable: true,
|
|
54
|
-
value: new Map()
|
|
55
|
-
});
|
|
56
|
-
Object.defineProperty(this, "imageCounter", {
|
|
49
|
+
}); // 文本占位符计数器
|
|
50
|
+
Object.defineProperty(this, "imagePlaceholderCounter", {
|
|
57
51
|
enumerable: true,
|
|
58
52
|
configurable: true,
|
|
59
53
|
writable: true,
|
|
60
54
|
value: 0
|
|
61
|
-
});
|
|
55
|
+
}); // 图片占位符计数器
|
|
62
56
|
Object.defineProperty(this, "pasteAccumulator", {
|
|
63
57
|
enumerable: true,
|
|
64
58
|
configurable: true,
|
|
@@ -126,20 +120,20 @@ export class TextBuffer {
|
|
|
126
120
|
clearTimeout(this.pasteTimer);
|
|
127
121
|
this.pasteTimer = null;
|
|
128
122
|
}
|
|
129
|
-
this.
|
|
130
|
-
this.imageStorage.clear();
|
|
123
|
+
this.placeholderStorage.clear();
|
|
131
124
|
this.onUpdateCallback = undefined;
|
|
132
125
|
}
|
|
133
126
|
get text() {
|
|
134
127
|
return this.content;
|
|
135
128
|
}
|
|
136
129
|
/**
|
|
137
|
-
*
|
|
130
|
+
* 获取完整文本,包括替换占位符为原始内容(仅文本类型)
|
|
138
131
|
*/
|
|
139
132
|
getFullText() {
|
|
140
133
|
let fullText = this.content;
|
|
141
|
-
for (const placeholder of this.
|
|
142
|
-
|
|
134
|
+
for (const placeholder of this.placeholderStorage.values()) {
|
|
135
|
+
// 只替换文本类型的占位符
|
|
136
|
+
if (placeholder.type === 'text' && placeholder.placeholder) {
|
|
143
137
|
fullText = fullText
|
|
144
138
|
.split(placeholder.placeholder)
|
|
145
139
|
.join(placeholder.content);
|
|
@@ -170,10 +164,9 @@ export class TextBuffer {
|
|
|
170
164
|
this.content = sanitized;
|
|
171
165
|
this.clampCursorIndex();
|
|
172
166
|
if (sanitized === '') {
|
|
173
|
-
this.
|
|
174
|
-
this.
|
|
175
|
-
this.
|
|
176
|
-
this.imageCounter = 0;
|
|
167
|
+
this.placeholderStorage.clear();
|
|
168
|
+
this.textPlaceholderCounter = 0;
|
|
169
|
+
this.imagePlaceholderCounter = 0;
|
|
177
170
|
this.pasteAccumulator = '';
|
|
178
171
|
if (this.pasteTimer) {
|
|
179
172
|
clearTimeout(this.pasteTimer);
|
|
@@ -250,14 +243,15 @@ export class TextBuffer {
|
|
|
250
243
|
this.content = this.content.replace(tempPlaceholderPattern, '');
|
|
251
244
|
// 只有当累积的字符数超过300时才创建占位符
|
|
252
245
|
if (totalChars > 300) {
|
|
253
|
-
this.
|
|
254
|
-
const pasteId = `paste_${Date.now()}_${this.
|
|
255
|
-
const placeholderText = `[Paste ${totalChars} characters #${this.
|
|
256
|
-
this.
|
|
246
|
+
this.textPlaceholderCounter++;
|
|
247
|
+
const pasteId = `paste_${Date.now()}_${this.textPlaceholderCounter}`;
|
|
248
|
+
const placeholderText = `[Paste ${totalChars} characters #${this.textPlaceholderCounter}]`;
|
|
249
|
+
this.placeholderStorage.set(pasteId, {
|
|
257
250
|
id: pasteId,
|
|
251
|
+
type: 'text',
|
|
258
252
|
content: this.pasteAccumulator,
|
|
259
253
|
charCount: totalChars,
|
|
260
|
-
index: this.
|
|
254
|
+
index: this.textPlaceholderCounter,
|
|
261
255
|
placeholder: placeholderText,
|
|
262
256
|
});
|
|
263
257
|
// 在记录的位置插入占位符
|
|
@@ -507,33 +501,57 @@ export class TextBuffer {
|
|
|
507
501
|
this.preferredVisualCol = this.visualCursorPos[1];
|
|
508
502
|
}
|
|
509
503
|
/**
|
|
510
|
-
*
|
|
504
|
+
* 插入图片数据(使用统一的占位符系统)
|
|
511
505
|
*/
|
|
512
506
|
insertImage(base64Data, mimeType) {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
const
|
|
516
|
-
this.
|
|
507
|
+
// 清理 base64 数据:移除所有空白字符(包括换行符)
|
|
508
|
+
// PowerShell/macOS 的 base64 编码可能包含换行符
|
|
509
|
+
const cleanedBase64 = base64Data.replace(/\s+/g, '');
|
|
510
|
+
this.imagePlaceholderCounter++;
|
|
511
|
+
const imageId = `image_${Date.now()}_${this.imagePlaceholderCounter}`;
|
|
512
|
+
const placeholderText = `[image #${this.imagePlaceholderCounter}]`;
|
|
513
|
+
this.placeholderStorage.set(imageId, {
|
|
517
514
|
id: imageId,
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
515
|
+
type: 'image',
|
|
516
|
+
content: cleanedBase64,
|
|
517
|
+
charCount: cleanedBase64.length,
|
|
518
|
+
index: this.imagePlaceholderCounter,
|
|
521
519
|
placeholder: placeholderText,
|
|
520
|
+
mimeType: mimeType,
|
|
522
521
|
});
|
|
523
522
|
this.insertPlainText(placeholderText);
|
|
524
523
|
this.scheduleUpdate();
|
|
525
524
|
}
|
|
526
525
|
/**
|
|
527
|
-
*
|
|
526
|
+
* 获取所有图片数据(还原为 data URL 格式)
|
|
528
527
|
*/
|
|
529
528
|
getImages() {
|
|
530
|
-
return Array.from(this.
|
|
529
|
+
return Array.from(this.placeholderStorage.values())
|
|
530
|
+
.filter((p) => p.type === 'image')
|
|
531
|
+
.map((p) => {
|
|
532
|
+
const mimeType = p.mimeType || 'image/png';
|
|
533
|
+
// 还原为 data URL 格式
|
|
534
|
+
const dataUrl = `data:${mimeType};base64,${p.content}`;
|
|
535
|
+
return {
|
|
536
|
+
id: p.id,
|
|
537
|
+
data: dataUrl,
|
|
538
|
+
mimeType: mimeType,
|
|
539
|
+
index: p.index,
|
|
540
|
+
placeholder: p.placeholder,
|
|
541
|
+
};
|
|
542
|
+
})
|
|
543
|
+
.sort((a, b) => a.index - b.index);
|
|
531
544
|
}
|
|
532
545
|
/**
|
|
533
546
|
* 清除所有图片
|
|
534
547
|
*/
|
|
535
548
|
clearImages() {
|
|
536
|
-
|
|
537
|
-
this.
|
|
549
|
+
// 只清除图片类型的占位符
|
|
550
|
+
for (const [id, placeholder] of this.placeholderStorage.entries()) {
|
|
551
|
+
if (placeholder.type === 'image') {
|
|
552
|
+
this.placeholderStorage.delete(id);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
this.imagePlaceholderCounter = 0;
|
|
538
556
|
}
|
|
539
557
|
}
|