5
5
IconPlayerStop ,
6
6
IconRepeat ,
7
7
IconSend ,
8
+ IconHelpCircleFilled
8
9
} from '@tabler/icons-react' ;
9
10
import {
10
11
KeyboardEvent ,
@@ -18,7 +19,7 @@ import {
18
19
19
20
import { useTranslation } from 'next-i18next' ;
20
21
21
- import { Message } from '@/types/chat' ;
22
+ import { Message , Conversation } from '@/types/chat' ;
22
23
import { Plugin } from '@/types/plugin' ;
23
24
import { Prompt } from '@/types/prompt' ;
24
25
@@ -28,6 +29,7 @@ import { PluginSelect } from './PluginSelect';
28
29
import { PromptList } from './PromptList' ;
29
30
import { VariableModal } from './VariableModal' ;
30
31
32
+
31
33
interface Props {
32
34
onSend : ( message : Message , plugin : Plugin | null ) => void ;
33
35
onRegenerate : ( ) => void ;
@@ -62,6 +64,8 @@ export const ChatInput = ({
62
64
const [ isModalVisible , setIsModalVisible ] = useState ( false ) ;
63
65
const [ showPluginSelect , setShowPluginSelect ] = useState ( false ) ;
64
66
const [ plugin , setPlugin ] = useState < Plugin | null > ( null ) ;
67
+ const [ promptCharacterLength , setPromptCharacterLength ] = useState ( 0 ) ;
68
+ const [ characterLength , setCharacterLength ] = useState ( 0 ) ;
65
69
66
70
const promptListRef = useRef < HTMLUListElement | null > ( null ) ;
67
71
@@ -71,22 +75,12 @@ export const ChatInput = ({
71
75
72
76
const handleChange = ( e : React . ChangeEvent < HTMLTextAreaElement > ) => {
73
77
const value = e . target . value ;
74
- const maxLength = selectedConversation ?. model . maxLength ;
75
-
76
- if ( maxLength && value . length > maxLength ) {
77
- alert (
78
- t (
79
- `Message limit is {{maxLength}} characters. You have entered {{valueLength}} characters.` ,
80
- { maxLength, valueLength : value . length } ,
81
- ) ,
82
- ) ;
83
- return ;
84
- }
85
-
78
+ setPromptCharacterLength ( ( selectedConversation ?. characterLength ?? 0 ) + value . length ) ;
86
79
setContent ( value ) ;
87
80
updatePromptListVisibility ( value ) ;
88
81
} ;
89
82
83
+
90
84
const handleSend = ( ) => {
91
85
if ( messageIsStreaming ) {
92
86
return ;
@@ -234,11 +228,12 @@ export const ChatInput = ({
234
228
textareaRef . current . style . height = 'inherit' ;
235
229
textareaRef . current . style . height = `${ textareaRef . current ?. scrollHeight } px` ;
236
230
textareaRef . current . style . overflow = `${
237
- textareaRef ?. current ?. scrollHeight > 400 ? 'auto' : 'hidden'
238
- } `;
231
+ textareaRef ?. current ?. scrollHeight > 400 ? 'auto' : 'hidden'
232
+ } `;
239
233
}
240
234
} , [ content ] ) ;
241
235
236
+
242
237
useEffect ( ( ) => {
243
238
const handleOutsideClick = ( e : MouseEvent ) => {
244
239
if (
@@ -256,9 +251,11 @@ export const ChatInput = ({
256
251
} ;
257
252
} , [ ] ) ;
258
253
254
+ const maxLength = selectedConversation ?. model . maxLength ?? 0 ;
255
+
259
256
return (
260
257
< div className = "absolute bottom-0 left-0 w-full border-transparent bg-gradient-to-b from-transparent via-white to-white pt-6 dark:border-white/20 dark:via-[#343541] dark:to-[#343541] md:pt-2" >
261
- < div className = "stretch mx-2 mt-4 flex flex-row gap-3 last:mb-2 md:mx-4 md:mt-[52px] md:last:mb-6 lg:mx-auto lg:max-w-3xl" >
258
+ < div className = "stretch mx-2 mt-4 flex flex-row gap-3 last:mb-2 md:mx-4 md:mt-[52px] md:last:mb-12 lg:mx-auto lg:max-w-3xl" >
262
259
{ messageIsStreaming && (
263
260
< button
264
261
className = "absolute top-0 left-0 right-0 mx-auto mb-3 flex w-fit items-center gap-3 rounded border border-neutral-200 bg-white py-2 px-4 text-black hover:opacity-50 dark:border-neutral-600 dark:bg-[#343541] dark:text-white md:mb-0 md:mt-2"
@@ -293,10 +290,10 @@ export const ChatInput = ({
293
290
bottom : `${ textareaRef ?. current ?. scrollHeight } px` ,
294
291
maxHeight : '400px' ,
295
292
overflow : `${
296
- textareaRef . current && textareaRef . current . scrollHeight > 400
297
- ? 'auto'
298
- : 'hidden'
299
- } `,
293
+ textareaRef . current && textareaRef . current . scrollHeight > 400
294
+ ? 'auto'
295
+ : 'hidden'
296
+ } `,
300
297
} }
301
298
placeholder = {
302
299
t ( 'Type a message ' ) || ''
@@ -358,7 +355,31 @@ export const ChatInput = ({
358
355
onClose = { ( ) => setIsModalVisible ( false ) }
359
356
/>
360
357
) }
358
+
359
+
360
+
361
+ { ( promptCharacterLength <= maxLength && promptCharacterLength > maxLength * .75 ) && (
362
+ < div className = "text-orange-500 m-4" >
363
+ Warning: you are approaching the number of words this model is able to handle. Consider starting a new conversation. Characters left: { maxLength - promptCharacterLength }
364
+
365
+ < span className = "inline-block relative top-[2px] pl-1"
366
+ title = "Once past the context limit, the conversation will no longer produce responses relevant to content before the limit" >
367
+ < IconHelpCircleFilled stroke = { 2 } size = { 16 } />
368
+ </ span >
369
+ </ div >
370
+ ) }
371
+
372
+ { promptCharacterLength > maxLength && (
373
+ < div className = "text-red-500 m-4" >
374
+ This prompt or conversation is too large for this model. Approximate number of characters over: { promptCharacterLength - maxLength }
375
+ < span className = "inline-block relative top-[2px] pl-1"
376
+ title = "Once past the context limit, the conversation will no longer produce responses relevant to content before the limit" >
377
+ < IconHelpCircleFilled stroke = { 2 } size = { 16 } />
378
+ </ span >
379
+ </ div >
380
+ ) }
361
381
</ div >
382
+
362
383
</ div >
363
384
</ div >
364
385
) ;
0 commit comments