Merge branch 'main' into system-prompt-variations-local

This commit is contained in:
Anirban Kar 2024-12-16 21:44:47 +05:30
commit d473b2b713
8 changed files with 225 additions and 99 deletions

View File

@ -29,7 +29,7 @@ jobs:
- name: Update commit file - name: Update commit file
run: | run: |
echo CURRENT_VERSION=$(node -p "require('./package.json').version") >> $GITHUB_ENV echo "CURRENT_VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV
echo "{ \"commit\": \"$COMMIT_HASH\" , \"version\": \"$CURRENT_VERSION\" }" > app/commit.json echo "{ \"commit\": \"$COMMIT_HASH\" , \"version\": \"$CURRENT_VERSION\" }" > app/commit.json
- name: Commit and push the update - name: Commit and push the update

View File

@ -1 +1 @@
{ "commit": "19a3a03d455a5042cd3f8c654b0498c4cde2ea75" } { "commit": "bb941802094c6186e805f99a6c165431ae86d216" }

View File

@ -73,8 +73,8 @@ export const Messages = React.forwardRef<HTMLDivElement, MessagesProps>((props:
</div> </div>
{!isUserMessage && ( {!isUserMessage && (
<div className="flex gap-2 flex-col lg:flex-row"> <div className="flex gap-2 flex-col lg:flex-row">
<WithTooltip tooltip="Revert to this message"> {messageId && (
{messageId && ( <WithTooltip tooltip="Revert to this message">
<button <button
onClick={() => handleRewind(messageId)} onClick={() => handleRewind(messageId)}
key="i-ph:arrow-u-up-left" key="i-ph:arrow-u-up-left"
@ -83,8 +83,8 @@ export const Messages = React.forwardRef<HTMLDivElement, MessagesProps>((props:
'text-xl text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary transition-colors', 'text-xl text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary transition-colors',
)} )}
/> />
)} </WithTooltip>
</WithTooltip> )}
<WithTooltip tooltip="Fork chat from this message"> <WithTooltip tooltip="Fork chat from this message">
<button <button

View File

@ -22,6 +22,12 @@ interface SystemInfo {
timezone: string; timezone: string;
memory: string; memory: string;
cores: number; cores: number;
deviceType: string;
colorDepth: string;
pixelRatio: number;
online: boolean;
cookiesEnabled: boolean;
doNotTrack: boolean;
} }
interface IProviderConfig { interface IProviderConfig {
@ -62,14 +68,100 @@ function getSystemInfo(): SystemInfo {
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}; };
const getBrowserInfo = (): string => {
const ua = navigator.userAgent;
let browser = 'Unknown';
if (ua.includes('Firefox/')) {
browser = 'Firefox';
} else if (ua.includes('Chrome/')) {
if (ua.includes('Edg/')) {
browser = 'Edge';
} else if (ua.includes('OPR/')) {
browser = 'Opera';
} else {
browser = 'Chrome';
}
} else if (ua.includes('Safari/')) {
if (!ua.includes('Chrome')) {
browser = 'Safari';
}
}
// Extract version number
const match = ua.match(new RegExp(`${browser}\\/([\\d.]+)`));
const version = match ? ` ${match[1]}` : '';
return `${browser}${version}`;
};
const getOperatingSystem = (): string => {
const ua = navigator.userAgent;
const platform = navigator.platform;
if (ua.includes('Win')) {
return 'Windows';
}
if (ua.includes('Mac')) {
if (ua.includes('iPhone') || ua.includes('iPad')) {
return 'iOS';
}
return 'macOS';
}
if (ua.includes('Linux')) {
return 'Linux';
}
if (ua.includes('Android')) {
return 'Android';
}
return platform || 'Unknown';
};
const getDeviceType = (): string => {
const ua = navigator.userAgent;
if (ua.includes('Mobile')) {
return 'Mobile';
}
if (ua.includes('Tablet')) {
return 'Tablet';
}
return 'Desktop';
};
// Get more detailed memory info if available
const getMemoryInfo = (): string => {
if ('memory' in performance) {
const memory = (performance as any).memory;
return `${formatBytes(memory.jsHeapSizeLimit)} (Used: ${formatBytes(memory.usedJSHeapSize)})`;
}
return 'Not available';
};
return { return {
os: navigator.platform, os: getOperatingSystem(),
browser: navigator.userAgent.split(' ').slice(-1)[0], browser: getBrowserInfo(),
screen: `${window.screen.width}x${window.screen.height}`, screen: `${window.screen.width}x${window.screen.height}`,
language: navigator.language, language: navigator.language,
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
memory: formatBytes(performance?.memory?.jsHeapSizeLimit || 0), memory: getMemoryInfo(),
cores: navigator.hardwareConcurrency || 0, cores: navigator.hardwareConcurrency || 0,
deviceType: getDeviceType(),
// Add new fields
colorDepth: `${window.screen.colorDepth}-bit`,
pixelRatio: window.devicePixelRatio,
online: navigator.onLine,
cookiesEnabled: navigator.cookieEnabled,
doNotTrack: navigator.doNotTrack === '1',
}; };
} }
@ -384,10 +476,31 @@ export default function DebugTab() {
<p className="text-xs text-bolt-elements-textSecondary">Operating System</p> <p className="text-xs text-bolt-elements-textSecondary">Operating System</p>
<p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.os}</p> <p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.os}</p>
</div> </div>
<div>
<p className="text-xs text-bolt-elements-textSecondary">Device Type</p>
<p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.deviceType}</p>
</div>
<div> <div>
<p className="text-xs text-bolt-elements-textSecondary">Browser</p> <p className="text-xs text-bolt-elements-textSecondary">Browser</p>
<p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.browser}</p> <p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.browser}</p>
</div> </div>
<div>
<p className="text-xs text-bolt-elements-textSecondary">Display</p>
<p className="text-sm font-medium text-bolt-elements-textPrimary">
{systemInfo.screen} ({systemInfo.colorDepth}) @{systemInfo.pixelRatio}x
</p>
</div>
<div>
<p className="text-xs text-bolt-elements-textSecondary">Connection</p>
<p className="text-sm font-medium flex items-center gap-2">
<span
className={`inline-block w-2 h-2 rounded-full ${systemInfo.online ? 'bg-green-500' : 'bg-red-500'}`}
/>
<span className={`${systemInfo.online ? 'text-green-600' : 'text-red-600'}`}>
{systemInfo.online ? 'Online' : 'Offline'}
</span>
</p>
</div>
<div> <div>
<p className="text-xs text-bolt-elements-textSecondary">Screen Resolution</p> <p className="text-xs text-bolt-elements-textSecondary">Screen Resolution</p>
<p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.screen}</p> <p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.screen}</p>

View File

@ -1,4 +1,4 @@
import { memo } from 'react'; import { memo, forwardRef, type ForwardedRef } from 'react';
import { classNames } from '~/utils/classNames'; import { classNames } from '~/utils/classNames';
type IconSize = 'sm' | 'md' | 'lg' | 'xl' | 'xxl'; type IconSize = 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
@ -25,41 +25,48 @@ type IconButtonWithChildrenProps = {
type IconButtonProps = IconButtonWithoutChildrenProps | IconButtonWithChildrenProps; type IconButtonProps = IconButtonWithoutChildrenProps | IconButtonWithChildrenProps;
// Componente IconButton com suporte a refs
export const IconButton = memo( export const IconButton = memo(
({ forwardRef(
icon, (
size = 'xl', {
className, icon,
iconClassName, size = 'xl',
disabledClassName, className,
disabled = false, iconClassName,
title, disabledClassName,
onClick, disabled = false,
children, title,
}: IconButtonProps) => { onClick,
return ( children,
<button }: IconButtonProps,
className={classNames( ref: ForwardedRef<HTMLButtonElement>,
'flex items-center text-bolt-elements-item-contentDefault bg-transparent enabled:hover:text-bolt-elements-item-contentActive rounded-md p-1 enabled:hover:bg-bolt-elements-item-backgroundActive disabled:cursor-not-allowed', ) => {
{ return (
[classNames('opacity-30', disabledClassName)]: disabled, <button
}, ref={ref}
className, className={classNames(
)} 'flex items-center text-bolt-elements-item-contentDefault bg-transparent enabled:hover:text-bolt-elements-item-contentActive rounded-md p-1 enabled:hover:bg-bolt-elements-item-backgroundActive disabled:cursor-not-allowed',
title={title} {
disabled={disabled} [classNames('opacity-30', disabledClassName)]: disabled,
onClick={(event) => { },
if (disabled) { className,
return; )}
} title={title}
disabled={disabled}
onClick={(event) => {
if (disabled) {
return;
}
onClick?.(event); onClick?.(event);
}} }}
> >
{children ? children : <div className={classNames(icon, getIconSize(size), iconClassName)}></div>} {children ? children : <div className={classNames(icon, getIconSize(size), iconClassName)}></div>}
</button> </button>
); );
}, },
),
); );
function getIconSize(size: IconSize) { function getIconSize(size: IconSize) {

View File

@ -1,8 +1,9 @@
import * as Tooltip from '@radix-ui/react-tooltip'; import * as Tooltip from '@radix-ui/react-tooltip';
import { forwardRef, type ForwardedRef, type ReactElement } from 'react';
interface TooltipProps { interface TooltipProps {
tooltip: React.ReactNode; tooltip: React.ReactNode;
children: React.ReactNode; children: ReactElement;
sideOffset?: number; sideOffset?: number;
className?: string; className?: string;
arrowClassName?: string; arrowClassName?: string;
@ -12,62 +13,67 @@ interface TooltipProps {
delay?: number; delay?: number;
} }
const WithTooltip = ({ const WithTooltip = forwardRef(
tooltip, (
children, {
sideOffset = 5, tooltip,
className = '', children,
arrowClassName = '', sideOffset = 5,
tooltipStyle = {}, className = '',
position = 'top', arrowClassName = '',
maxWidth = 250, tooltipStyle = {},
delay = 0, position = 'top',
}: TooltipProps) => { maxWidth = 250,
return ( delay = 0,
<Tooltip.Root delayDuration={delay}> }: TooltipProps,
<Tooltip.Trigger asChild>{children}</Tooltip.Trigger> _ref: ForwardedRef<HTMLElement>,
<Tooltip.Portal> ) => {
<Tooltip.Content return (
side={position} <Tooltip.Root delayDuration={delay}>
className={` <Tooltip.Trigger asChild>{children}</Tooltip.Trigger>
z-[2000] <Tooltip.Portal>
px-2.5 <Tooltip.Content
py-1.5 side={position}
max-h-[300px]
select-none
rounded-md
bg-bolt-elements-background-depth-3
text-bolt-elements-textPrimary
text-sm
leading-tight
shadow-lg
animate-in
fade-in-0
zoom-in-95
data-[state=closed]:animate-out
data-[state=closed]:fade-out-0
data-[state=closed]:zoom-out-95
${className}
`}
sideOffset={sideOffset}
style={{
maxWidth,
...tooltipStyle,
}}
>
<div className="break-words">{tooltip}</div>
<Tooltip.Arrow
className={` className={`
fill-bolt-elements-background-depth-3 z-[2000]
${arrowClassName} px-2.5
py-1.5
max-h-[300px]
select-none
rounded-md
bg-bolt-elements-background-depth-3
text-bolt-elements-textPrimary
text-sm
leading-tight
shadow-lg
animate-in
fade-in-0
zoom-in-95
data-[state=closed]:animate-out
data-[state=closed]:fade-out-0
data-[state=closed]:zoom-out-95
${className}
`} `}
width={12} sideOffset={sideOffset}
height={6} style={{
/> maxWidth,
</Tooltip.Content> ...tooltipStyle,
</Tooltip.Portal> }}
</Tooltip.Root> >
); <div className="break-words">{tooltip}</div>
}; <Tooltip.Arrow
className={`
fill-bolt-elements-background-depth-3
${arrowClassName}
`}
width={12}
height={6}
/>
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
);
},
);
export default WithTooltip; export default WithTooltip;

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
public/apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB