This commit is contained in:
seb
2026-10-06 11:40:02 +02:00
parent 03608017f3
commit 4769a87c54
6 changed files with 1197 additions and 20 deletions

View File

@@ -23,6 +23,8 @@ import EscalatorWarningIcon from '@mui/icons-material/EscalatorWarning';
import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf';
import ManageSearchIcon from '@mui/icons-material/ManageSearch';
import HealingMarkdown from './HealingMarkdown';
import { ChatMessageAttachments } from './ChatAttachmentItems';
import ChatAttachmentPreviewModal from './ChatAttachmentPreviewModal';
import {
CHROMA,
SHADOW_BUBBLE_ASSISTANT,
@@ -725,12 +727,30 @@ export function normalizeChatMessages(rawMessages = []) {
}
const payload = parseMessagePayload(msg.message);
let attachments = Array.isArray(msg.attachments) ? [...msg.attachments] : [];
if (attachments.length === 0 && Array.isArray(payload.attachments)) {
attachments = [...payload.attachments];
}
let userText = payload.content !== undefined ? payload.content : msg.message;
if (typeof userText === 'string' && userText.startsWith('{')) {
try {
const nested = JSON.parse(userText);
if (nested && typeof nested === 'object') {
if (nested.content !== undefined) userText = nested.content;
if (Array.isArray(nested.attachments) && attachments.length === 0) {
attachments = [...nested.attachments];
}
}
} catch {}
}
if (msg.role === 'user') {
flushAssistant();
result.push({
...msg,
message: payload.content !== undefined ? payload.content : msg.message,
message: userText,
attachments,
});
continue;
}
@@ -826,7 +846,7 @@ export function normalizeChatMessages(rawMessages = []) {
return result;
}
function MessageRow({ msg, showTime = true }) {
function MessageRow({ msg, showTime = true, onPreviewAttachment }) {
// If the message has structured turns, render each turn
if (msg.turns && Array.isArray(msg.turns) && msg.turns.length > 0) {
return (
@@ -839,7 +859,22 @@ function MessageRow({ msg, showTime = true }) {
}
const payload = parseMessagePayload(msg.message);
const textContent = payload.content !== undefined ? payload.content : msg.message;
let textContent = payload.content !== undefined ? payload.content : msg.message;
let attachments = Array.isArray(msg.attachments) ? msg.attachments : [];
if (attachments.length === 0 && Array.isArray(payload.attachments)) {
attachments = payload.attachments;
}
if (typeof textContent === 'string' && textContent.startsWith('{')) {
try {
const nested = JSON.parse(textContent);
if (nested && typeof nested === 'object') {
if (nested.content !== undefined) textContent = nested.content;
if (Array.isArray(nested.attachments) && attachments.length === 0) {
attachments = nested.attachments;
}
}
} catch {}
}
if (msg.role === 'system') {
return (
@@ -917,11 +952,21 @@ function MessageRow({ msg, showTime = true }) {
lineHeight: 1.5,
})}
>
{isUser ? (
textContent
) : (
<HealingMarkdown text={textContent} streaming={msg.streaming} />
{attachments && attachments.length > 0 && (
<ChatMessageAttachments
attachments={attachments}
isUser={isUser}
onPreview={onPreviewAttachment}
/>
)}
{textContent ? (
isUser ? (
textContent
) : (
<HealingMarkdown text={textContent} streaming={msg.streaming} />
)
) : null}
</Box>
</Box>
</Box>
@@ -933,6 +978,18 @@ export default class ChatFlowList extends PureComponent {
bottomRef = createRef();
scrollTimeout = null;
state = {
previewAttachment: null,
};
handlePreviewAttachment = (attachment) => {
this.setState({ previewAttachment: attachment });
};
handleClosePreview = () => {
this.setState({ previewAttachment: null });
};
componentDidMount() {
this.scrollToBottom('auto');
}
@@ -974,6 +1031,7 @@ export default class ChatFlowList extends PureComponent {
render() {
const { messages = [], activeTurns = [] } = this.props;
const { previewAttachment } = this.state;
const normalizedMessages = normalizeChatMessages(messages);
if (normalizedMessages.length === 0 && activeTurns.length === 0) {
@@ -1007,6 +1065,7 @@ export default class ChatFlowList extends PureComponent {
key={msg.id || index}
msg={msg}
showTime={showTime}
onPreviewAttachment={this.handlePreviewAttachment}
/>
);
})}
@@ -1019,6 +1078,12 @@ export default class ChatFlowList extends PureComponent {
: null}
<div ref={this.bottomRef} style={{ height: 1, flexShrink: 0 }} />
<ChatAttachmentPreviewModal
open={Boolean(previewAttachment)}
attachment={previewAttachment}
onClose={this.handleClosePreview}
/>
</Box>
);
}