File size: 3,701 Bytes
834cad6
53763e2
9f076f8
b0c21fa
e5b6f72
53763e2
88ab17b
 
 
054d282
328552e
9285db9
53763e2
 
 
 
 
 
 
 
 
 
9285db9
 
88ab17b
9285db9
054d282
9f076f8
82ddd60
 
4c905d5
 
 
82ddd60
 
e772681
f616dbf
 
2a8011b
82ddd60
f616dbf
2a8011b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8e0db75
ecb5f4b
2a8011b
82ddd60
2a8011b
82ddd60
 
cb43691
054d282
916e00a
53763e2
 
916e00a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53763e2
 
 
 
916e00a
d3becdb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"use client"
import { useSearchParams } from 'next/navigation'
import { useEffect, useState } from "react";
import { MemoizedReactMarkdown } from '../../../components/MemoizedReactMarkdown'
import { CodeBlock } from '../../../components/CodeBlock';
import WebSearchResults from '../../../components/WebSearchResults';

export default function WebSearchPage() {
  const searchParams = useSearchParams()

  const [aiResponse, setAiResponse] = useState("");
  const [searchTerm, setSearchTerm] = useState()
  const [searchResults, setSearchResults] = useState([]);

  useEffect(() => {
    try {
      const streamArray = JSON.parse(aiResponse);
      setSearchResults(streamArray);
    } catch (err) {
      return;
    }
  }, [aiResponse])

  useEffect(() => {
    setSearchTerm(searchParams.get('searchTerm'))
  }, [searchParams])

  useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;
    if (!searchTerm) {
      return;
    }
  
    async function fetchData() {
      const response = await fetch('/api/llm', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ question: searchTerm }),
        signal,
      });
      const data = response.body;
      if (!data) {
        return;
      }

      const reader = data.getReader();
      const decoder = new TextDecoder();
      let done = false;

      while (!done) {
        const { value, done: doneReading } = await reader.read();
        done = doneReading;
        const chunkValue = decoder.decode(value);
        if (chunkValue) {
          setAiResponse(chunkValue);
        }
      }
    };
  
    fetchData();
  
    return () => controller.abort();
  }, [searchParams, searchTerm]);

  return (
    <>
      {!searchResults.length ? <div style={{ padding: "20px" }} className="flex flex-row">
        <MemoizedReactMarkdown
          className="prose dark:prose-invert flex-1"
          components={{
            code({ node, inline, className, children, ...props }) {
              if (children.length) {
                if (children[0] == '▍') {
                  return <span className="animate-pulse cursor-default mt-1">▍</span>
                }
                children[0] = (children[0]).replace("`▍`", "▍")
              }
              const match = /language-(\w+)/.exec(className || '');
              return !inline ? (
                <CodeBlock
                  key={Math.random()}
                  language={(match && match[1]) || ''}
                  value={String(children).replace(/\n$/, '')}
                  {...props}
                />
              ) : (
                <code className={className} {...props}>
                  {children}
                </code>
              );
            },
            table({ children }) {
              return (
                <table className="border-collapse border border-black px-3 py-1 dark:border-white">
                  {children}
                </table>
              );
            },
            th({ children }) {
              return (
                <th className="break-words border border-black bg-gray-500 px-3 py-1 text-white dark:border-white">
                  {children}
                </th>
              );
            },
            td({ children }) {
              return (
                <td className="break-words border border-black px-3 py-1 dark:border-white">
                  {children}
                </td>
              );
            },
          }}
        >
          {aiResponse}         
        </MemoizedReactMarkdown> 
      </div> : <WebSearchResults results={searchResults} />}
      </>
    );
}