diff --git a/backend/src/agents/middlewares/uploads_middleware.py b/backend/src/agents/middlewares/uploads_middleware.py index 152512c..04f7018 100644 --- a/backend/src/agents/middlewares/uploads_middleware.py +++ b/backend/src/agents/middlewares/uploads_middleware.py @@ -189,7 +189,20 @@ class UploadsMiddleware(AgentMiddleware[UploadsMiddlewareState]): # Create files message and prepend to the last human message content files_message = self._create_files_message(files) - original_content = last_message.content if isinstance(last_message.content, str) else "" + + # Extract original content - handle both string and list formats + original_content = "" + if isinstance(last_message.content, str): + original_content = last_message.content + elif isinstance(last_message.content, list): + # Content is a list of content blocks (e.g., [{"type": "text", "text": "..."}]) + text_parts = [] + for block in last_message.content: + if isinstance(block, dict) and block.get("type") == "text": + text_parts.append(block.get("text", "")) + original_content = "\n".join(text_parts) + + logger.info(f"Original message content: {original_content[:100] if original_content else '(empty)'}") # Create new message with combined content updated_message = HumanMessage( diff --git a/frontend/src/components/workspace/messages/message-list-item.tsx b/frontend/src/components/workspace/messages/message-list-item.tsx index 9b6206d..5f41c6e 100644 --- a/frontend/src/components/workspace/messages/message-list-item.tsx +++ b/frontend/src/components/workspace/messages/message-list-item.tsx @@ -115,6 +115,86 @@ function MessageContent_({ const { thread_id } = useParams<{ thread_id: string }>(); + // For human messages with uploaded files, render files outside the bubble + if (isHuman && uploadedFiles.length > 0) { + return ( +
+ {/* Uploaded files outside the message bubble */} + + + {/* Message content inside the bubble (only if there's text) */} + {cleanContent && ( + + ) => { + if (!href) { + return {children}; + } + + // Check if this link matches a citation + const citation = citationMap.get(href); + if (citation) { + return ( + + {children} + + ); + } + + // Regular external link + return ( + + {children} + + ); + }, + img: ({ src, alt }: React.ImgHTMLAttributes) => { + if (!src) return null; + if (typeof src !== "string") { + return ( + {alt} + ); + } + let url = src; + if (src.startsWith("/mnt/")) { + url = resolveArtifactURL(src, thread_id); + } + return ( + + {alt} + + ); + }, + }} + > + {cleanContent} + + + )} +
+ ); + } + + // Default rendering for non-human messages or human messages without files return ( {/* Uploaded files for human messages - show first */} @@ -287,7 +367,7 @@ function UploadedFileCard({ href={imageUrl} target="_blank" rel="noopener noreferrer" - className="group relative block overflow-hidden rounded-lg border" + className="group relative block overflow-hidden rounded-lg border border-border/40" > +
{ const text = message.text.trim(); + + console.log('[useSubmitThread] Submitting message:', { + text, + hasFiles: !!message.files?.length, + filesCount: message.files?.length || 0 + }); // Upload files first if any if (message.files && message.files.length > 0) {