fix: Bridge 图片消息在桌面端聊天记录中回显
conversation-engine 保存用户消息时,复用桌面端 chat route 的存储格式:
- 将 base64 图片写入 .codepilot-uploads/ 目录
- 用 <!--files:[{id,name,type,size,filePath}]--> 格式嵌入消息 content
- 桌面 UI 的 MessageItem.parseMessageFiles() 可直接解析并通过
FileAttachmentDisplay + /api/uploads 渲染图片
将 getSession() 调用提前到 addMessage 之前,确保 workingDirectory 可用。
写入失败时降级为 [N image(s) attached] 文本指示。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
887870c343
commit
69d33df5b6
1 file changed
+33
-6
@@ -6,6 +6,8 @@
|
||||
* and returns the response text for delivery.
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import type { ChannelBinding } from './types';
|
||||
import type { SSEEvent, TokenUsage, MessageContentBlock, FileAttachment } from '@/types';
|
||||
import { streamClaude } from '../claude-client';
|
||||
@@ -87,14 +89,39 @@ export async function processMessage(
|
||||
}, 60_000);
|
||||
|
||||
try {
|
||||
// Save user message (with image indicator if attachments present)
|
||||
const userMsgText = files && files.length > 0
|
||||
? `[${files.length} image(s) attached] ${text}`
|
||||
: text;
|
||||
addMessage(sessionId, 'user', userMsgText);
|
||||
// Resolve session early — needed for workingDirectory and provider resolution
|
||||
const session = getSession(sessionId);
|
||||
|
||||
// Save user message — persist file attachments to disk using the same
|
||||
// <!--files:JSON--> format as the desktop chat route, so the UI can render them.
|
||||
let savedContent = text;
|
||||
if (files && files.length > 0) {
|
||||
const workDir = binding.workingDirectory || session?.working_directory || '';
|
||||
if (workDir) {
|
||||
try {
|
||||
const uploadDir = path.join(workDir, '.codepilot-uploads');
|
||||
if (!fs.existsSync(uploadDir)) {
|
||||
fs.mkdirSync(uploadDir, { recursive: true });
|
||||
}
|
||||
const fileMeta = files.map((f) => {
|
||||
const safeName = path.basename(f.name).replace(/[^a-zA-Z0-9._-]/g, '_');
|
||||
const filePath = path.join(uploadDir, `${Date.now()}-${safeName}`);
|
||||
const buffer = Buffer.from(f.data, 'base64');
|
||||
fs.writeFileSync(filePath, buffer);
|
||||
return { id: f.id, name: f.name, type: f.type, size: buffer.length, filePath };
|
||||
});
|
||||
savedContent = `<!--files:${JSON.stringify(fileMeta)}-->${text}`;
|
||||
} catch (err) {
|
||||
console.warn('[conversation-engine] Failed to persist file attachments:', err instanceof Error ? err.message : err);
|
||||
savedContent = `[${files.length} image(s) attached] ${text}`;
|
||||
}
|
||||
} else {
|
||||
savedContent = `[${files.length} image(s) attached] ${text}`;
|
||||
}
|
||||
}
|
||||
addMessage(sessionId, 'user', savedContent);
|
||||
|
||||
// Resolve provider
|
||||
const session = getSession(sessionId);
|
||||
let resolvedProvider: import('@/types').ApiProvider | undefined;
|
||||
const providerId = session?.provider_id || '';
|
||||
if (providerId && providerId !== 'env') {
|
||||
|
||||
Reference in new issue
Block a user