fix: Image Agent 模式下图片不回显、不调用生成工具的问题
三个连锁 Bug 的根因修复: 1. route.ts — 图片 base64 数据保留 - 之前:文件存盘后一律清空 base64 data(包括图片) - 现在:只对非图片文件清空 data,图片始终保留 base64 - 确保 SDK 收到有效的 image content block 用于 vision 2. types/index.ts — ClaudeStreamOptions 增加 imageAgentMode 标记 - 新增 imageAgentMode?: boolean 字段 - 由 route.ts 根据 systemPromptAppend 是否存在来设置 3. claude-client.ts — buildFinalPrompt 在 imageAgentMode 下跳过文件路径引用 - imageAgentMode=true 时不添加 [User attached image: /path] 文本 - 防止 Claude 看到路径后调用 analyze_image 等内置工具 - Claude 仅通过 vision(base64 content blocks)看到图片 - 遵循 IMAGE_AGENT_SYSTEM_PROMPT 输出 image-gen-request 块 - 普通模式行为不变,仍保留路径引用供 skill/工具使用 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
d13a0396f9
commit
b5233d0257
3 files changed
+19
-9
No files matched your search
@@ -149,7 +149,7 @@ export async function POST(request: NextRequest) {
|
||||
name: f.name,
|
||||
type: f.type,
|
||||
size: f.size,
|
||||
data: meta?.filePath ? '' : f.data, // Skip base64 data if file is already saved to disk
|
||||
data: (meta?.filePath && !f.type.startsWith('image/')) ? '' : f.data, // Keep base64 for images (needed for vision); clear for non-images (read from disk)
|
||||
filePath: meta?.filePath,
|
||||
};
|
||||
})
|
||||
@@ -189,6 +189,7 @@ export async function POST(request: NextRequest) {
|
||||
abortController,
|
||||
permissionMode,
|
||||
files: fileAttachments,
|
||||
imageAgentMode: !!systemPromptAppend,
|
||||
toolTimeoutSeconds: toolTimeout || 300,
|
||||
provider: resolvedProvider,
|
||||
conversationHistory: historyMsgs,
|
||||
|
||||
@@ -279,6 +279,7 @@ export function streamClaude(options: ClaudeStreamOptions): ReadableStream<strin
|
||||
toolTimeoutSeconds = 0,
|
||||
conversationHistory,
|
||||
onRuntimeStatusChange,
|
||||
imageAgentMode,
|
||||
} = options;
|
||||
|
||||
return new ReadableStream<string>({
|
||||
@@ -612,14 +613,21 @@ export function streamClaude(options: ClaudeStreamOptions): ReadableStream<strin
|
||||
}
|
||||
|
||||
if (imageFiles.length > 0) {
|
||||
// Append image disk paths to the text prompt so Claude knows where
|
||||
// the files are on disk (enables skills to reference them by path).
|
||||
const workDir = workingDirectory || os.homedir();
|
||||
const imagePaths = getUploadedFilePaths(imageFiles, workDir);
|
||||
const imageReferences = imagePaths
|
||||
.map((p, i) => `[User attached image: ${p} (${imageFiles[i].name})]`)
|
||||
.join('\n');
|
||||
const textWithImageRefs = `${imageReferences}\n\n${textPrompt}`;
|
||||
// In imageAgentMode, skip file path references so Claude doesn't
|
||||
// try to use built-in tools to analyze images from disk. It will
|
||||
// see the images via vision (base64 content blocks) and follow the
|
||||
// IMAGE_AGENT_SYSTEM_PROMPT to output image-gen-request blocks.
|
||||
// In normal mode, append disk paths so skills can reference them.
|
||||
const textWithImageRefs = imageAgentMode
|
||||
? textPrompt
|
||||
: (() => {
|
||||
const workDir = workingDirectory || os.homedir();
|
||||
const imagePaths = getUploadedFilePaths(imageFiles, workDir);
|
||||
const imageReferences = imagePaths
|
||||
.map((p, i) => `[User attached image: ${p} (${imageFiles[i].name})]`)
|
||||
.join('\n');
|
||||
return `${imageReferences}\n\n${textPrompt}`;
|
||||
})();
|
||||
|
||||
const contentBlocks: Array<
|
||||
| { type: 'image'; source: { type: 'base64'; media_type: string; data: string } }
|
||||
|
||||
@@ -644,6 +644,7 @@ export interface ClaudeStreamOptions {
|
||||
abortController?: AbortController;
|
||||
permissionMode?: string;
|
||||
files?: FileAttachment[];
|
||||
imageAgentMode?: boolean;
|
||||
toolTimeoutSeconds?: number;
|
||||
provider?: ApiProvider;
|
||||
/** Recent conversation history from DB — used as fallback context when SDK resume is unavailable or fails */
|
||||
|
||||
Reference in new issue
Block a user