Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions phd-advisor-frontend/src/components/EnhancedChatInput.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useRef, useEffect } from 'react';
import { Send, Paperclip, FileText, X, Trash2, Download } from 'lucide-react';
import { Send, Paperclip, FileText, X, Trash2, Download, Users, Sparkles } from 'lucide-react';
import FileUpload from './FileUpload';

const EnhancedChatInput = ({
Expand All @@ -8,8 +8,10 @@ const EnhancedChatInput = ({
uploadedDocuments = [],
isLoading,
currentChatSessionId,
authToken,
placeholder = "Ask your advisors anything..."
authToken,
placeholder = "Ask your advisors anything...",
responseMode = 'panel',
onResponseModeChange,
}) => {
const [inputMessage, setInputMessage] = useState('');
const [showUpload, setShowUpload] = useState(false);
Expand Down Expand Up @@ -204,6 +206,19 @@ const EnhancedChatInput = ({
<span className="docs-count">{uploadedDocuments.length}</span>
</button>
)}

<button
onClick={() => onResponseModeChange?.(responseMode === 'panel' ? 'aggregated' : 'panel')}
className={`add-docs-btn response-mode-toggle ${responseMode === 'aggregated' ? 'active' : ''}`}
type="button"
title={responseMode === 'panel'
? 'Currently: Multiple Responses — click to switch to a single Generalized Response'
: 'Currently: Generalized Response — click to switch back to Multiple Responses'}
disabled={isDisabled}
>
{responseMode === 'aggregated' ? <Sparkles size={16} /> : <Users size={16} />}
<span>{responseMode === 'aggregated' ? 'Generalized response' : 'Multiple responses'}</span>
</button>
</div>

{/* Right - Send Button */}
Expand Down
17 changes: 15 additions & 2 deletions phd-advisor-frontend/src/components/MessageBubble.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,23 @@ const MessageBubble = ({
return (
<div className={`advisor-message-container ${inlineAvatar ? 'inline-avatar-mode' : ''}`}>
{!inlineAvatar && (
<div
className="advisor-avatar"
<div
className="advisor-avatar"
style={{ backgroundColor: colors.bgColor || 'var(--bg-muted)', overflow: 'hidden' }}
>
{advisor.avatarUrl ? (
<img
src={advisor.avatarUrl}
alt={advisor.name || 'Advisor'}
style={{ width: '100%', height: '100%', borderRadius: '50%', objectFit: 'cover' }}
/>
) : Icon ? (
<Icon style={{ color: colors.color || 'var(--text-secondary)', width: 20, height: 20 }} />
) : (
<span style={{ color: colors.color || 'var(--text-secondary)', fontWeight: 600, fontSize: 16 }}>
{(advisor.name || message.advisorName || 'A').charAt(0)}
</span>
)}
</div>
)}

Expand Down
16 changes: 15 additions & 1 deletion phd-advisor-frontend/src/contexts/AppConfigContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,21 @@ export const AppConfigProvider = ({ children }) => {
}, []);

useEffect(() => {
setAdvisors(buildAdvisors(personaItems, avatarOverrides));
const built = buildAdvisors(personaItems, avatarOverrides);
// Synthetic persona used for aggregated/synthesized responses — represents
// a single combined "Partner" voice rather than the panel of advisors.
built.aggregated = {
name: 'Partner',
role: 'Synthesized Response',
description: 'A single combined response merging all advisor perspectives.',
color: '#7C3AED',
bgColor: '#F3E8FF',
darkColor: '#A78BFA',
darkBgColor: '#3B2A5E',
icon: LucideIcons.User,
avatarUrl: avatarOverrides.aggregated || null,
};
setAdvisors(built);
}, [personaItems, avatarOverrides]);

const setAdvisorAvatar = (advisorId, url) => {
Expand Down
Loading