Bumped tool limit and updated alerts (#2274)

This commit is contained in:
Zane
2025-04-21 18:25:39 -07:00
committed by GitHub
parent 80feb6da60
commit cb72617d5e
4 changed files with 54 additions and 36 deletions

View File

@@ -6,6 +6,7 @@ export enum AlertType {
export interface Alert {
type: AlertType;
message: string;
autoShow?: boolean;
action?: {
text: string;
onClick: () => void;

View File

@@ -1,13 +1,19 @@
import { useState, useCallback } from 'react';
import { Alert, AlertType } from './types';
interface AlertOptions {
type: AlertType;
message: string;
action?: {
text: string;
onClick: () => void;
};
autoShow?: boolean;
}
interface UseAlerts {
alerts: Alert[];
addAlert: (
type: AlertType,
message: string,
action?: { text: string; onClick: () => void }
) => void;
addAlert: (options: AlertOptions) => void;
removeAlert: (index: number) => void;
clearAlerts: () => void;
}
@@ -15,12 +21,9 @@ interface UseAlerts {
export const useAlerts = (): UseAlerts => {
const [alerts, setAlerts] = useState<Alert[]>([]);
const addAlert = useCallback(
(type: AlertType, message: string, action?: { text: string; onClick: () => void }) => {
setAlerts((prev) => [...prev, { type, message, action }]);
},
[]
);
const addAlert = useCallback((options: AlertOptions) => {
setAlerts((prev) => [...prev, options]);
}, []);
const removeAlert = useCallback((index: number) => {
setAlerts((prev) => prev.filter((_, i) => i !== index));

View File

@@ -11,11 +11,11 @@ import { settingsV2Enabled } from '../../flags';
import { BottomMenuModeSelection } from './BottomMenuModeSelection';
import ModelsBottomBar from '../settings_v2/models/bottom_bar/ModelsBottomBar';
import { useConfig } from '../ConfigContext';
import { getCurrentModelAndProvider } from '../settings_v2/models/index';
import { getCurrentModelAndProvider } from '../settings_v2/models';
const TOKEN_LIMIT_DEFAULT = 128000; // fallback for custom models that the backend doesn't know about
const TOKEN_WARNING_THRESHOLD = 0.8; // warning shows at 80% of the token limit
const TOOLS_MAX_SUGGESTED = 25; // max number of tools before we show a warning
const TOOLS_MAX_SUGGESTED = 60; // max number of tools before we show a warning
export default function BottomMenu({
hasMessages,
@@ -73,28 +73,31 @@ export default function BottomMenu({
// Add token alerts if we have a token limit
if (tokenLimit && numTokens > 0) {
if (numTokens >= tokenLimit) {
addAlert(
AlertType.Error,
`Token limit reached (${numTokens.toLocaleString()}/${tokenLimit.toLocaleString()})`
);
addAlert({
type: AlertType.Error,
message: `Token limit reached (${numTokens.toLocaleString()}/${tokenLimit.toLocaleString()}) \n Youve reached the models conversation limit. The session will be saved — copy anything important and start a new one to continue.`,
autoShow: true, // Auto-show token limit errors
});
} else if (numTokens >= tokenLimit * TOKEN_WARNING_THRESHOLD) {
addAlert(
AlertType.Warning,
`Approaching token limit (${numTokens.toLocaleString()}/${tokenLimit.toLocaleString()})`
);
addAlert({
type: AlertType.Warning,
message: `Approaching token limit (${numTokens.toLocaleString()}/${tokenLimit.toLocaleString()}) \n Youre reaching the models conversation limit. The session will be saved — copy anything important and start a new one to continue.`,
autoShow: true, // Auto-show token limit warnings
});
}
}
// Add tool count alert if we have the data
if (toolCount !== null && toolCount > TOOLS_MAX_SUGGESTED) {
addAlert(
AlertType.Warning,
`Too many tools can degrade performance.\nTool count: ${toolCount} (recommend: ${TOOLS_MAX_SUGGESTED})`,
{
addAlert({
type: AlertType.Warning,
message: `Too many tools can degrade performance.\nTool count: ${toolCount} (recommend: ${TOOLS_MAX_SUGGESTED})`,
action: {
text: 'View extensions',
onClick: () => setView('settings'),
}
);
},
autoShow: false, // Don't auto-show tool count warnings
});
}
// We intentionally omit setView as it shouldn't trigger a re-render of alerts
// eslint-disable-next-line react-hooks/exhaustive-deps

View File

@@ -1,5 +1,6 @@
import React, { useRef, useEffect, useCallback } from 'react';
import { IoIosCloseCircle, IoIosWarning } from 'react-icons/io';
import { FaCircle } from 'react-icons/fa';
import { IoIosCloseCircle } from 'react-icons/io';
import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';
import { cn } from '../../utils';
import { Alert, AlertType } from '../alerts';
@@ -37,16 +38,21 @@ export default function BottomMenuAlertPopover({ alerts }: AlertPopoverProps) {
useEffect(() => {
if (alerts.length === 0) return;
// Compare current and previous alerts for any changes
const hasChanges = alerts.some((alert, index) => {
// Find new or changed alerts
const changedAlerts = alerts.filter((alert, index) => {
const prevAlert = previousAlertsRef.current[index];
return !prevAlert || prevAlert.type !== alert.type || prevAlert.message !== alert.message;
});
previousAlertsRef.current = alerts;
// Auto show the popover if there are new alerts
if (!hasShownInitial || hasChanges) {
// Only auto-show if any of the new/changed alerts have autoShow: true
const hasNewAutoShowAlert = changedAlerts.some((alert) => alert.autoShow === true);
// Auto show the popover only if:
// 1. There are new alerts that should auto-show AND
// 2. We haven't shown this specific alert before (tracked by hasShownInitial)
if (hasNewAutoShowAlert && !hasShownInitial) {
setIsOpen(true);
setHasShownInitial(true);
setWasAutoShown(true);
@@ -83,18 +89,23 @@ export default function BottomMenuAlertPopover({ alerts }: AlertPopoverProps) {
if (alerts.length === 0) return null;
// Determine the icon to show based on the highest priority alert
// Determine the icon and styling based on the alerts
const hasError = alerts.some((alert) => alert.type === AlertType.Error);
const TriggerIcon = hasError ? IoIosCloseCircle : IoIosWarning;
const TriggerIcon = hasError ? IoIosCloseCircle : FaCircle;
const triggerColor = hasError ? 'text-[#d7040e]' : 'text-[#cc4b03]';
// Different styling for error icon vs notification dot
const iconStyles = hasError
? 'h-5 w-5' // Keep error icon larger
: 'h-2.5 w-2.5'; // Smaller notification dot
return (
<div ref={popoverRef}>
<Popover open={isOpen}>
<div className="relative">
<PopoverTrigger asChild>
<div
className="cursor-pointer flex items-center"
className="cursor-pointer flex items-center justify-center min-w-5 min-h-5 translate-y-[1px]"
onClick={() => {
if (hideTimerRef.current) {
clearTimeout(hideTimerRef.current);
@@ -114,7 +125,7 @@ export default function BottomMenuAlertPopover({ alerts }: AlertPopoverProps) {
setIsHovered(false);
}}
>
<TriggerIcon className={cn('h-5 w-5', triggerColor)} />
<TriggerIcon className={cn(iconStyles, triggerColor)} />
</div>
</PopoverTrigger>