@yeaft/webchat-agent 0.1.355 → 0.1.356
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/claude.js +62 -0
- package/package.json +1 -1
package/claude.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { writeFile, mkdir } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
1
3
|
import { query, Stream } from './sdk/index.js';
|
|
2
4
|
import ctx from './context.js';
|
|
3
5
|
import { sendConversationList, sendOutput, sendError, handleAskUserQuestion } from './conversation.js';
|
|
@@ -511,6 +513,9 @@ async function processClaudeOutput(conversationId, claudeQuery, state) {
|
|
|
511
513
|
// 检测后台任务
|
|
512
514
|
detectAndTrackBackgroundTask(conversationId, state, message);
|
|
513
515
|
|
|
516
|
+
// Extract image blocks from assistant/tool_result messages, save locally, forward to server
|
|
517
|
+
await extractAndSendChatImages(conversationId, state, message);
|
|
518
|
+
|
|
514
519
|
// Debug: log assistant messages to help diagnose duplicate output issues
|
|
515
520
|
if (message.type === 'assistant') {
|
|
516
521
|
const text = typeof message.message?.content === 'string'
|
|
@@ -609,6 +614,63 @@ async function processClaudeOutput(conversationId, claudeQuery, state) {
|
|
|
609
614
|
}
|
|
610
615
|
}
|
|
611
616
|
|
|
617
|
+
/**
|
|
618
|
+
* Extract image content blocks from a Claude SDK message, save to local files,
|
|
619
|
+
* and send chat_image messages to server. Images are persisted under workDir/.data/images/.
|
|
620
|
+
* Handles both assistant messages (image blocks) and user/tool_result messages (screenshot results).
|
|
621
|
+
*/
|
|
622
|
+
let _imageCounter = 0;
|
|
623
|
+
async function extractAndSendChatImages(conversationId, state, message) {
|
|
624
|
+
let contentBlocks = null;
|
|
625
|
+
|
|
626
|
+
// assistant messages: image blocks in message.message.content
|
|
627
|
+
if (message.type === 'assistant' && Array.isArray(message.message?.content)) {
|
|
628
|
+
contentBlocks = message.message.content;
|
|
629
|
+
}
|
|
630
|
+
// user/tool_result messages: image blocks in message.message.content (tool results with screenshots)
|
|
631
|
+
if (message.type === 'user' && Array.isArray(message.message?.content)) {
|
|
632
|
+
contentBlocks = message.message.content;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
if (!contentBlocks) return;
|
|
636
|
+
|
|
637
|
+
for (const block of contentBlocks) {
|
|
638
|
+
if (block.type === 'image' && block.source?.type === 'base64' && block.source?.data) {
|
|
639
|
+
try {
|
|
640
|
+
const mimeType = block.source.media_type || 'image/png';
|
|
641
|
+
const ext = (mimeType.split('/')[1] || 'png').replace('jpeg', 'jpg');
|
|
642
|
+
const imageDir = join(state.workDir, '.data', 'images');
|
|
643
|
+
await mkdir(imageDir, { recursive: true });
|
|
644
|
+
|
|
645
|
+
const filename = `chat-${Date.now()}-${++_imageCounter}.${ext}`;
|
|
646
|
+
const filePath = join(imageDir, filename);
|
|
647
|
+
const buffer = Buffer.from(block.source.data, 'base64');
|
|
648
|
+
|
|
649
|
+
// Size check: skip images larger than 10MB
|
|
650
|
+
if (buffer.length > 10 * 1024 * 1024) {
|
|
651
|
+
console.warn(`[Chat Image] Image too large: ${buffer.length} bytes, skipping`);
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
await writeFile(filePath, buffer);
|
|
656
|
+
console.log(`[Chat Image] Saved: ${filePath} (${buffer.length} bytes, ${mimeType})`);
|
|
657
|
+
|
|
658
|
+
// Send to server with base64 data for immediate serving + filePath for persistence reference
|
|
659
|
+
ctx.sendToServer({
|
|
660
|
+
type: 'chat_image',
|
|
661
|
+
conversationId,
|
|
662
|
+
mimeType,
|
|
663
|
+
data: block.source.data,
|
|
664
|
+
filePath,
|
|
665
|
+
filename
|
|
666
|
+
});
|
|
667
|
+
} catch (err) {
|
|
668
|
+
console.error(`[Chat Image] Failed to save image:`, err.message);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
|
|
612
674
|
/**
|
|
613
675
|
* 从 tools 列表中提取 MCP server 名称和 per-server tools 映射。
|
|
614
676
|
* MCP 工具名称格式: mcp__<serverName>__<toolName>
|