Open LucasMagnum opened 15 hours ago
To fix the bug where the get_avatar
function fails to load avatars correctly for threads in history when config.ui.name
contains spaces, you need to ensure that the author
parameter in the URL is properly encoded. This can be done using encodeURIComponent
to handle spaces and other special characters.
Here is the modified code for the MessageAvatar
component:
import { useContext, useMemo } from 'react';
import { Tooltip } from '@mui/material';
import Avatar from '@mui/material/Avatar';
import {
ChainlitContext,
useChatSession,
useConfig
} from '@chainlit/react-client';
interface Props {
author?: string;
hide?: boolean;
}
const MessageAvatar = ({ author, hide }: Props) => {
const apiClient = useContext(ChainlitContext);
const { chatProfile } = useChatSession();
const { config } = useConfig();
const selectedChatProfile = useMemo(() => {
return config?.chatProfiles.find((profile) => profile.name === chatProfile);
}, [config, chatProfile]);
const avatarUrl = useMemo(() => {
const isAssistant = !author || author === config?.ui.name;
if (isAssistant && selectedChatProfile?.icon) {
return selectedChatProfile.icon;
}
return apiClient?.buildEndpoint(`/avatars/${encodeURIComponent(author || 'default')}`);
}, [apiClient, selectedChatProfile, config, author]);
return (
<span className={`message-avatar`}>
<Tooltip title={author}>
<Avatar
sx={{
width: '1.6rem',
height: '1.6rem',
bgcolor: 'transparent'
}}
src={hide ? undefined : avatarUrl}
/>
</Tooltip>
</span>
);
};
export { MessageAvatar };
By using encodeURIComponent
on the author
parameter, you ensure that any spaces or special characters are correctly encoded, preventing the 400 error [1].
Additionally, the get_avatar
function in the backend handles the avatar_id
parameter by validating it, normalizing it, and searching for a matching avatar file. Here is the implementation:
@router.get("/avatars/{avatar_id:str}")
async def get_avatar(avatar_id: str):
"""Get the avatar for the user based on the avatar_id."""
if not re.match(r"^[a-zA-Z0-9_-]+$", avatar_id):
raise HTTPException(status_code=400, detail="Invalid avatar_id")
if avatar_id == "default":
avatar_id = config.ui.name
avatar_id = avatar_id.strip().lower().replace(" ", "_")
base_path = Path(APP_ROOT) / "public" / "avatars"
avatar_pattern = f"{avatar_id}.*"
matching_files = base_path.glob(avatar_pattern)
if avatar_path := next(matching_files, None):
if not is_path_inside(avatar_path, base_path):
raise HTTPException(status_code=400, detail="Invalid filename")
media_type, _ = mimetypes.guess_type(str(avatar_path))
return FileResponse(avatar_path, media_type=media_type)
return await get_favicon()
This function ensures that the avatar_id
is properly formatted and validated before attempting to retrieve the avatar file [2].
To continue talking to Dosu, mention @dosu.
Describe the bug
The PR https://github.com/Chainlit/chainlit/pull/1326 introduces a bug when it expects the
get_avatar
to match string (https://github.com/Chainlit/chainlit/pull/1326/files#diff-9a73e67e163edc3fae6839bf2bcc8c6ab650624eff6668502388a7a86b7ece78R964) .The Frontend app can make requests to the avatar that do not match the Regex (https://github.com/Chainlit/chainlit/blob/main/frontend/src/components/molecules/messages/components/Avatar.tsx#L31) this creates a bug for existing applications where the
config.ui.name
contains space (e.g.My Assistant
).To Reproduce Set your config.ui.name to
My Assistant
Expected behavior Avatar should be loaded for threads in history.