diff --git a/src/api/chat.ts b/src/api/chat.ts index b068a0b..c3f5686 100644 --- a/src/api/chat.ts +++ b/src/api/chat.ts @@ -15,7 +15,11 @@ export interface ToolCallTrace { export interface ChatMessage { id: string; - role: 'user' | 'assistant'; + role: 'user' | 'assistant' | 'agent' | 'system'; + speaker?: { + id: string; + type: 'user' | 'agent'; + }; content: string; reasoning?: string | null; parentId?: string | null; @@ -73,4 +77,3 @@ export const ChatAttachmentsAPI = { return api.post<{ files: ChatAttachment[] }>('/chat/attachments', fd).then((r) => r.data); } }; - diff --git a/src/pages/chat/components/ChatBody.tsx b/src/pages/chat/components/ChatBody.tsx index 2d6741a..2b79f24 100644 --- a/src/pages/chat/components/ChatBody.tsx +++ b/src/pages/chat/components/ChatBody.tsx @@ -60,7 +60,7 @@ export default function ChatBody(props: { agentList={agentList} currentAgentId={currentAgentId} highlighted={highlightId === m.id} - branch={m.role === 'assistant' && m.parentId ? branches[m.parentId] : undefined} + branch={((m as any)?.speaker?.type ? (m as any).speaker.type === 'agent' : m.role === 'assistant') && m.parentId ? branches[m.parentId] : undefined} busy={sending} onRegenerate={onRegenerate} onSwitchBranch={onSwitchBranch} @@ -76,7 +76,9 @@ export default function ChatBody(props: { const streamingAgent = agentList.find(a => a.id === streamingAgentId); if (streamingAgent) { return ( - + + {streamingAgent.name?.charAt(0)?.toUpperCase() || 'A'} + ); } return null; diff --git a/src/pages/chat/components/ChatOutline.tsx b/src/pages/chat/components/ChatOutline.tsx index bcdc7d8..906cbde 100644 --- a/src/pages/chat/components/ChatOutline.tsx +++ b/src/pages/chat/components/ChatOutline.tsx @@ -14,7 +14,7 @@ function summarize(content: string) { export default function ChatOutline(props: { messages: ChatMessage[]; onJump: (id: string) => void; activeId?: string | null }) { const { messages, onJump, activeId } = props; - const items = messages.filter((m) => m.role === 'assistant'); + const items = messages.filter((m) => ((m as any)?.speaker?.type ? (m as any).speaker.type === 'agent' : m.role === 'assistant')); if (items.length === 0) return null; @@ -38,4 +38,3 @@ export default function ChatOutline(props: { messages: ChatMessage[]; onJump: (i ); } - diff --git a/src/pages/chat/components/messages/MessageItem.tsx b/src/pages/chat/components/messages/MessageItem.tsx index 00745fa..9906ce5 100644 --- a/src/pages/chat/components/messages/MessageItem.tsx +++ b/src/pages/chat/components/messages/MessageItem.tsx @@ -19,8 +19,12 @@ export default function MessageItem(props: { }) { const { message, agentList, currentAgentId, highlighted, branch, busy, onRegenerate, onSwitchBranch, onCopy } = props; + const speakerType = (message as any)?.speaker?.type as ('user' | 'agent' | undefined); + const isUser = speakerType ? speakerType === 'user' : message.role === 'user'; + const bubbleRole = isUser ? 'user' : 'assistant'; + // 获取回答者 Agent 信息 - const answerAgentId = message.agent_id || (message.role === 'assistant' ? currentAgentId : undefined); + const answerAgentId = message.agent_id || (!isUser ? currentAgentId : undefined); const answerAgent = answerAgentId ? agentList.find(a => a.id === answerAgentId) : undefined; const hasBranches = !!branch && branch.total > 1; const activeIdx = branch?.activeIndex ?? 0; @@ -49,9 +53,8 @@ export default function MessageItem(props: { transition: 'background 0.4s, padding 0.4s' }} > - {message.role === 'assistant' ? ( + {!isUser ? (
- {/* AGENT: 头像在左侧,内容在右侧(靠左对齐) */}
-
+
{message.content}
@@ -124,8 +127,7 @@ export default function MessageItem(props: {
) : (
- {/* 用户: 头像在右侧,内容在左侧(靠右对齐) */} -
+
-
+
{message.content.includes('![image](') ? ( {message.content} ) : ( diff --git a/src/styles.css b/src/styles.css index a4c51f5..0fd6285 100644 --- a/src/styles.css +++ b/src/styles.css @@ -628,6 +628,7 @@ body { .bubble { max-width: 78%; + display: inline-block; padding: 14px 18px; border-radius: 14px; margin-bottom: 14px; @@ -638,18 +639,18 @@ body { } .bubble.user { - background: var(--color-brand-soft); - color: var(--color-text); + background: #0a84ff; + color: #ffffff; margin-left: auto; border-bottom-right-radius: 5px; } .bubble.assistant { - background: #ffffff; - color: var(--color-text); - border: 1px solid var(--color-border); + background: #e9e9eb; + color: #111827; + border: 0; border-bottom-left-radius: 5px; - box-shadow: var(--shadow-xs); + box-shadow: none; } .bubble.assistant p {