@@ -55,10 +55,35 @@ padding: 4px 14px; border-radius: 16px; margin-right: 8px; - background-color: #7F7DF31A; + background-color: #7f7df31a; gap: 4px; + + :global(svg path) { + fill: currentColor; + } +} + +.predictPrice_low { + color: #10b981; + background-color: rgba(16, 185, 129, 0.12); +} + +.predictPrice_mid { + color: #f59e0b; + background-color: rgba(245, 158, 11, 0.12); +} + +.predictPrice_high { + color: #f15179; + background-color: rgba(241, 81, 121, 0.12); +} + +.predictPrice_default { + color: #7f7df3; + background-color: #7f7df31a; } .generationIcon { margin-top: 3px; + color: inherit; } @@ -1,4 +1,4 @@ -import React, { FC, useCallback, useEffect, useRef } from 'react' +import React, { FC, useCallback, useEffect, useMemo, useRef } from 'react' import { TextFieldProps } from '@mui/material/TextField/TextField' import classes from './model-input.module.scss' @@ -7,9 +7,26 @@ import { LoadImage } from '#/app/components/input_components/load_image' import { SendBtn } from '#/app/components/input_components/send_button' import { IModelInputs } from '#/shared/api/models/models' import { TooltipCustom } from '#/shared' +import { + predictPriceHighColor, + predictPriceLowColor, + predictPriceMidColor, + baseColor, +} from '#/shared/lib/constants/colors' import { SvgIcon } from '#/shared/ui/svg' import { Typography } from '@mui/material' -import { ThreePOutlined } from '@mui/icons-material' + +const PREDICT_PRICE_HIGH_TOOLTIP_DESKTOP = + 'Генерация может выйти очень дорогой, т.к вы ввели очень большой запрос или в чате накопились большие сообщения. Если хотите уменьшить стоимость генерации — создайте новый чат или уменьшите запрос' + +type PredictPriceTier = 'default' | 'low' | 'mid' | 'high' + +function getPredictPriceTier(tokens: number): PredictPriceTier { + if (!Number.isFinite(tokens) || tokens <= 0) return 'default' + if (tokens < 75) return 'low' + if (tokens < 150) return 'mid' + return 'high' +} interface Input { loading: boolean @@ -79,6 +96,31 @@ export const ModelInput: FC = ({ [sendMessage] ) + const predictPriceMeta = useMemo(() => { + if (typeof predictedPrice !== 'string') return null + const tokens = Math.ceil(Number(predictedPrice)) + const tier = getPredictPriceTier(tokens) + const tierClass = + tier === 'low' + ? classes.predictPrice_low + : tier === 'mid' + ? classes.predictPrice_mid + : tier === 'high' + ? classes.predictPrice_high + : classes.predictPrice_default + const textColor = + tier === 'low' + ? predictPriceLowColor + : tier === 'mid' + ? predictPriceMidColor + : tier === 'high' + ? predictPriceHighColor + : baseColor + const tooltipTitle = + tier === 'high' && desktop ? PREDICT_PRICE_HIGH_TOOLTIP_DESKTOP : 'Стоимость генерации' + return { tokens, tierClass, textColor, tooltipTitle } + }, [predictedPrice, desktop]) + useEffect(() => { if (input_types) { setRequired(input_types.map((el) => (el.required ? el.type : null))) @@ -181,13 +223,17 @@ export const ModelInput: FC = ({ >