MingruiZhang commited on
Commit
cc43e3c
1 Parent(s): a665cd2

lift 10 image restriction

Browse files
app/api/chat/route.ts CHANGED
@@ -33,6 +33,7 @@ export async function POST(req: Request) {
33
  const formattedMessage: ChatCompletionMessageParam[] = messages.map(
34
  message => {
35
  const { dataset, ...rest } = message;
 
36
 
37
  const contentWithImage: ChatCompletionContentPart[] = [
38
  {
 
33
  const formattedMessage: ChatCompletionMessageParam[] = messages.map(
34
  message => {
35
  const { dataset, ...rest } = message;
36
+ console.log('[Ming] ~ POST ~ dataset:', dataset?.length);
37
 
38
  const contentWithImage: ChatCompletionContentPart[] = [
39
  {
components/chat/ImageList.tsx CHANGED
@@ -15,7 +15,7 @@ const ImageList: React.FC<ImageListProps> = () => {
15
  const [dataset, setDataset] = useAtom(datasetAtom);
16
  return (
17
  <div className="relative size-full px-12 max-w-3xl mx-auto">
18
- {dataset.length < 10 ? (
19
  <div className="col-span-full px-8 py-4 rounded-xl bg-blue-100 text-blue-400 mb-8">
20
  You can upload up to 10 images max by dragging image.
21
  </div>
@@ -23,7 +23,7 @@ const ImageList: React.FC<ImageListProps> = () => {
23
  <div className="col-span-full px-8 py-4 rounded-xl bg-red-100 text-red-400 mb-8">
24
  You have reached the maximum limit of 10 images.
25
  </div>
26
- )}
27
  <div
28
  {...getRootProps()}
29
  className="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-4"
 
15
  const [dataset, setDataset] = useAtom(datasetAtom);
16
  return (
17
  <div className="relative size-full px-12 max-w-3xl mx-auto">
18
+ {/* {dataset.length < 10 ? (
19
  <div className="col-span-full px-8 py-4 rounded-xl bg-blue-100 text-blue-400 mb-8">
20
  You can upload up to 10 images max by dragging image.
21
  </div>
 
23
  <div className="col-span-full px-8 py-4 rounded-xl bg-red-100 text-red-400 mb-8">
24
  You have reached the maximum limit of 10 images.
25
  </div>
26
+ )} */}
27
  <div
28
  {...getRootProps()}
29
  className="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-4"
components/prompt-form.tsx CHANGED
@@ -1,52 +1,52 @@
1
- import * as React from 'react'
2
- import Textarea from 'react-textarea-autosize'
3
- import { UseChatHelpers } from 'ai/react'
4
- import { useEnterSubmit } from '@/lib/hooks/use-enter-submit'
5
- import { cn } from '@/lib/utils'
6
- import { Button, buttonVariants } from '@/components/ui/button'
7
  import {
8
- Tooltip,
9
- TooltipContent,
10
- TooltipTrigger
11
- } from '@/components/ui/tooltip'
12
- import { IconArrowElbow, IconPlus } from '@/components/ui/icons'
13
- import { useRouter } from 'next/navigation'
14
 
15
  export interface PromptProps
16
- extends Pick<UseChatHelpers, 'input' | 'setInput'> {
17
- onSubmit: (value: string) => void
18
- isLoading: boolean
19
  }
20
 
21
  export function PromptForm({
22
- onSubmit,
23
- input,
24
- setInput,
25
- isLoading
26
  }: PromptProps) {
27
- const { formRef, onKeyDown } = useEnterSubmit()
28
- const inputRef = React.useRef<HTMLTextAreaElement>(null)
29
- const router = useRouter()
30
- React.useEffect(() => {
31
- if (inputRef.current) {
32
- inputRef.current.focus()
33
- }
34
- }, [])
35
 
36
- return (
37
- <form
38
- onSubmit={async e => {
39
- e.preventDefault()
40
- if (!input?.trim()) {
41
- return
42
- }
43
- setInput('')
44
- await onSubmit(input)
45
- }}
46
- ref={formRef}
47
- >
48
- <div className="relative flex flex-col w-full px-8 pl-2 overflow-hidden max-h-60 grow bg-background sm:rounded-md sm:border sm:px-12 sm:pl-2">
49
- {/* <Tooltip>
50
  <TooltipTrigger asChild>
51
  <button
52
  onClick={e => {
@@ -65,33 +65,33 @@ export function PromptForm({
65
  </TooltipTrigger>
66
  <TooltipContent>New Chat</TooltipContent>
67
  </Tooltip> */}
68
- <Textarea
69
- ref={inputRef}
70
- tabIndex={0}
71
- onKeyDown={onKeyDown}
72
- rows={1}
73
- value={input}
74
- onChange={e => setInput(e.target.value)}
75
- placeholder="Send a message."
76
- spellCheck={false}
77
- className="min-h-[60px] w-full resize-none bg-transparent px-4 py-[1.3rem] focus-within:outline-none sm:text-sm"
78
- />
79
- <div className="absolute right-0 top-4 sm:right-4">
80
- <Tooltip>
81
- <TooltipTrigger asChild>
82
- <Button
83
- type="submit"
84
- size="icon"
85
- disabled={isLoading || input === ''}
86
- >
87
- <IconArrowElbow />
88
- <span className="sr-only">Send message</span>
89
- </Button>
90
- </TooltipTrigger>
91
- <TooltipContent>Send message</TooltipContent>
92
- </Tooltip>
93
- </div>
94
- </div>
95
- </form>
96
- )
97
  }
 
1
+ import * as React from 'react';
2
+ import Textarea from 'react-textarea-autosize';
3
+ import { UseChatHelpers } from 'ai/react';
4
+ import { useEnterSubmit } from '@/lib/hooks/use-enter-submit';
5
+ import { cn } from '@/lib/utils';
6
+ import { Button, buttonVariants } from '@/components/ui/button';
7
  import {
8
+ Tooltip,
9
+ TooltipContent,
10
+ TooltipTrigger,
11
+ } from '@/components/ui/tooltip';
12
+ import { IconArrowElbow, IconPlus } from '@/components/ui/icons';
13
+ import { useRouter } from 'next/navigation';
14
 
15
  export interface PromptProps
16
+ extends Pick<UseChatHelpers, 'input' | 'setInput'> {
17
+ onSubmit: (value: string) => void;
18
+ isLoading: boolean;
19
  }
20
 
21
  export function PromptForm({
22
+ onSubmit,
23
+ input,
24
+ setInput,
25
+ isLoading,
26
  }: PromptProps) {
27
+ const { formRef, onKeyDown } = useEnterSubmit();
28
+ const inputRef = React.useRef<HTMLTextAreaElement>(null);
29
+ const router = useRouter();
30
+ React.useEffect(() => {
31
+ if (inputRef.current) {
32
+ inputRef.current.focus();
33
+ }
34
+ }, []);
35
 
36
+ return (
37
+ <form
38
+ onSubmit={async e => {
39
+ e.preventDefault();
40
+ if (!input?.trim()) {
41
+ return;
42
+ }
43
+ setInput('');
44
+ await onSubmit(input);
45
+ }}
46
+ ref={formRef}
47
+ >
48
+ <div className="relative flex flex-col w-full px-8 pl-2 overflow-hidden max-h-60 grow bg-background sm:rounded-md sm:border sm:px-12 sm:pl-2">
49
+ {/* <Tooltip>
50
  <TooltipTrigger asChild>
51
  <button
52
  onClick={e => {
 
65
  </TooltipTrigger>
66
  <TooltipContent>New Chat</TooltipContent>
67
  </Tooltip> */}
68
+ <Textarea
69
+ ref={inputRef}
70
+ tabIndex={0}
71
+ onKeyDown={onKeyDown}
72
+ rows={1}
73
+ value={input}
74
+ onChange={e => setInput(e.target.value)}
75
+ placeholder="Ask questions about all or selected the images."
76
+ spellCheck={false}
77
+ className="min-h-[60px] w-full resize-none bg-transparent px-4 py-[1.3rem] focus-within:outline-none sm:text-sm"
78
+ />
79
+ <div className="absolute right-0 top-4 sm:right-4">
80
+ <Tooltip>
81
+ <TooltipTrigger asChild>
82
+ <Button
83
+ type="submit"
84
+ size="icon"
85
+ disabled={isLoading || input === ''}
86
+ >
87
+ <IconArrowElbow />
88
+ <span className="sr-only">Send message</span>
89
+ </Button>
90
+ </TooltipTrigger>
91
+ <TooltipContent>Send message</TooltipContent>
92
+ </Tooltip>
93
+ </div>
94
+ </div>
95
+ </form>
96
+ );
97
  }
lib/hooks/useChatWithDataset.ts CHANGED
@@ -73,14 +73,14 @@ const useChatWithDataset = () => {
73
  dataset;
74
 
75
  const appendWithDataset: typeof append = message => {
76
- const newSystemMessage: Message = {
77
- id: 'fake-id',
78
- content:
79
- 'For the next prompt, here are names of images provided by user, please use these name if you need reference: ' +
80
- selectedDataset.map(entity => entity.name).join(', '),
81
- role: 'system',
82
- };
83
- setMessages([...messages, newSystemMessage]);
84
  return append({
85
  ...message,
86
  // @ts-ignore this is extra fields
 
73
  dataset;
74
 
75
  const appendWithDataset: typeof append = message => {
76
+ // const newSystemMessage: Message = {
77
+ // id: 'fake-id',
78
+ // content:
79
+ // 'For the next prompt, here are names of images provided by user, please use these name if you need reference: ' +
80
+ // selectedDataset.map(entity => entity.name).join(', '),
81
+ // role: 'system',
82
+ // };
83
+ // setMessages([...messages, newSystemMessage]);
84
  return append({
85
  ...message,
86
  // @ts-ignore this is extra fields
lib/hooks/useImageUpload.ts CHANGED
@@ -12,12 +12,12 @@ const useImageUpload = (options?: Partial<DropzoneOptions>) => {
12
  },
13
  multiple: true,
14
  onDrop: acceptedFiles => {
15
- if (acceptedFiles.length > 10) {
16
- toast('You can only upload 10 images max.', {
17
- icon: '⚠️',
18
- });
19
- }
20
- acceptedFiles.slice(0, 10).forEach(file => {
21
  try {
22
  const reader = new FileReader();
23
  reader.onloadend = () => {
@@ -25,7 +25,7 @@ const useImageUpload = (options?: Partial<DropzoneOptions>) => {
25
  setTarget(prev => {
26
  // Check if the image already exists in the state
27
  if (
28
- prev.length >= 10 ||
29
  prev.find(entity => entity.url === newImage)
30
  ) {
31
  // If it does, return the state unchanged
 
12
  },
13
  multiple: true,
14
  onDrop: acceptedFiles => {
15
+ // if (acceptedFiles.length > 10) {
16
+ // toast('You can only upload 10 images max.', {
17
+ // icon: '⚠️',
18
+ // });
19
+ // }
20
+ acceptedFiles.forEach(file => {
21
  try {
22
  const reader = new FileReader();
23
  reader.onloadend = () => {
 
25
  setTarget(prev => {
26
  // Check if the image already exists in the state
27
  if (
28
+ // prev.length >= 10 ||
29
  prev.find(entity => entity.url === newImage)
30
  ) {
31
  // If it does, return the state unchanged