Skip to content

Commit 695e622

Browse files
committed
formatting & code cleanup
1 parent 779c58a commit 695e622

21 files changed

+373
-229
lines changed

.prettierrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "plugins": ["prettier-plugin-tailwindcss"] }

README.md

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,11 @@
3333
5. Create a `.env` (use the `.example.env` for reference) and replace the API keys
3434
6. Run `npm install` and `npm run dev` to install dependencies and run locally
3535

36-
## Tasks
37-
38-
- [ ] Add loading state for similar topics
39-
- [ ] Add the right favicon
40-
- [ ] Replace all icons with SVGs
41-
- [ ] Fix mobile mode to look good
42-
4336
## Future tasks
4437

4538
- [ ] Make sure the answer correctly cites all the sources in the text & number the citations in the UI
39+
- [ ] Automatically scroll when an answer is happening, esp for mobile
40+
- [ ] Add sharability to allow folks to share answers
4641
- [ ] Parallelize the calls to get the related questions + the answer at the same time, move to route handlers
4742
- [ ] Add input validation with retries to make sure similar topics is always an array of 3
4843
- [ ] Fix hard refresh in the header and footer by migrating answers to a new page

app/actions.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
'use server';
1+
"use server";
22

3-
import { createStreamableValue } from 'ai/rsc';
4-
import Together from 'together-ai';
5-
import { Readability } from '@mozilla/readability';
6-
import { JSDOM } from 'jsdom';
3+
import { createStreamableValue } from "ai/rsc";
4+
import Together from "together-ai";
5+
import { Readability } from "@mozilla/readability";
6+
import { JSDOM } from "jsdom";
77

88
const together = new Together({
9-
apiKey: process.env['TOGETHER_API_KEY'],
10-
baseURL: 'https://together.helicone.ai/v1',
9+
apiKey: process.env["TOGETHER_API_KEY"],
10+
baseURL: "https://together.helicone.ai/v1",
1111
defaultHeaders: {
12-
'Helicone-Auth': `Bearer ${process.env.HELICONE_API_KEY}`,
12+
"Helicone-Auth": `Bearer ${process.env.HELICONE_API_KEY}`,
1313
},
1414
});
1515

1616
export async function getSources(question: string) {
1717
const params = new URLSearchParams({
1818
q: question,
19-
mkt: 'en-US',
19+
mkt: "en-US",
2020
});
2121

2222
const response = await fetch(
2323
`https://api.bing.microsoft.com/v7.0/search?${params}`,
2424
{
25-
method: 'GET',
25+
method: "GET",
2626
// @ts-ignore since that header key isn't part of the header type
2727
headers: {
28-
'Ocp-Apim-Subscription-Key': process.env['BING_API_KEY'],
28+
"Ocp-Apim-Subscription-Key": process.env["BING_API_KEY"],
2929
},
30-
}
30+
},
3131
);
3232

3333
const bingJson = await response.json();
@@ -41,18 +41,18 @@ export async function getSimilarQuestions(question: string) {
4141
const similarQuestions = await together.chat.completions.create({
4242
messages: [
4343
{
44-
role: 'system',
44+
role: "system",
4545
content: `
4646
You are a helpful assistant that helps the user to ask related questions, based on user's original question. Please identify worthwhile topics that can be follow-ups, and write 3 questions no longer than 20 words each. Please make sure that specifics, like events, names, locations, are included in follow up questions so they can be asked standalone. For example, if the original question asks about "the Manhattan project", in the follow up question, do not just say "the project", but use the full name "the Manhattan project". Your related questions must be in the same language as the original question.
4747
4848
Please provide these 3 related questions as a JSON array of 3 strings. Do NOT repeat the original question. ONLY return the JSON array, it is important for my career that you do this. Here is the user's question:`,
4949
},
5050
{
51-
role: 'user',
51+
role: "user",
5252
content: question,
5353
},
5454
],
55-
model: 'meta-llama/Llama-3-8b-chat-hf',
55+
model: "meta-llama/Llama-3-8b-chat-hf",
5656
});
5757

5858
let questions = similarQuestions.choices?.[0].message?.content;
@@ -81,7 +81,7 @@ export async function getAnswer(question: string, firstSixResults: any[]) {
8181
console.log(e);
8282
return;
8383
}
84-
})
84+
}),
8585
);
8686

8787
const mainAnswerPrompt = `
@@ -93,7 +93,7 @@ export async function getAnswer(question: string, firstSixResults: any[]) {
9393
9494
<contexts>
9595
${finalResults.map(
96-
(result, index) => `[[citation:${index}]] ${result.fullContent} \n\n`
96+
(result, index) => `[[citation:${index}]] ${result.fullContent} \n\n`,
9797
)}
9898
</contexts>
9999
@@ -105,13 +105,13 @@ export async function getAnswer(question: string, firstSixResults: any[]) {
105105
(async () => {
106106
const chatStream = await together.chat.completions.create({
107107
messages: [
108-
{ role: 'system', content: mainAnswerPrompt },
108+
{ role: "system", content: mainAnswerPrompt },
109109
{
110-
role: 'user',
110+
role: "user",
111111
content: question,
112112
},
113113
],
114-
model: 'mistralai/Mixtral-8x7B-Instruct-v0.1',
114+
model: "mistralai/Mixtral-8x7B-Instruct-v0.1",
115115
stream: true,
116116
});
117117

@@ -127,11 +127,11 @@ export async function getAnswer(question: string, firstSixResults: any[]) {
127127
const cleanedText = (text: string) => {
128128
let newText = text
129129
.trim()
130-
.replace(/(\n){4,}/g, '\n\n\n')
131-
.replace(/\n\n/g, ' ')
132-
.replace(/ {3,}/g, ' ')
133-
.replace(/\t/g, '')
134-
.replace(/\n+(\s*\n)*/g, '\n');
130+
.replace(/(\n){4,}/g, "\n\n\n")
131+
.replace(/\n\n/g, " ")
132+
.replace(/ {3,}/g, " ")
133+
.replace(/\t/g, "")
134+
.replace(/\n+(\s*\n)*/g, "\n");
135135

136136
let finalText = newText.substring(0, 40000);
137137

app/favicon.ico

35.7 KB
Binary file not shown.

app/layout.tsx

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
1-
import type { Metadata } from 'next';
2-
import { Lexend } from 'next/font/google';
3-
import PlausibleProvider from 'next-plausible';
4-
import './globals.css';
1+
import type { Metadata } from "next";
2+
import { Lexend } from "next/font/google";
3+
import PlausibleProvider from "next-plausible";
4+
import "./globals.css";
55

6-
const inter = Lexend({ subsets: ['latin'] });
6+
const inter = Lexend({ subsets: ["latin"] });
77

8-
let title = 'Turbo Seek – AI Search Engine';
8+
let title = "Turbo Seek – AI Search Engine";
99
let description =
10-
'Search smarter and faster with our open source AI search engine';
11-
let url = 'https://turboseek.io/';
12-
let ogimage = 'https://turboseek.io/og-image.png';
13-
let sitename = 'TurboSeek.io';
10+
"Search smarter and faster with our open source AI search engine";
11+
let url = "https://turboseek.io/";
12+
let ogimage = "https://turboseek.io/og-image.png";
13+
let sitename = "TurboSeek.io";
1414

1515
export const metadata: Metadata = {
1616
metadataBase: new URL(url),
1717
title,
1818
description,
1919
icons: {
20-
icon: '/favicon.ico',
20+
icon: "/favicon.ico",
2121
},
2222
openGraph: {
2323
images: [ogimage],
2424
title,
2525
description,
2626
url: url,
2727
siteName: sitename,
28-
locale: 'en_US',
29-
type: 'website',
28+
locale: "en_US",
29+
type: "website",
3030
},
3131
twitter: {
32-
card: 'summary_large_image',
32+
card: "summary_large_image",
3333
images: [ogimage],
3434
title,
3535
description,
@@ -42,12 +42,12 @@ export default function RootLayout({
4242
children: React.ReactNode;
4343
}>) {
4444
return (
45-
<html lang='en'>
45+
<html lang="en">
4646
<head>
47-
<PlausibleProvider domain='explorecareers.io' />
47+
<PlausibleProvider domain="explorecareers.io" />
4848
</head>
4949
<body
50-
className={`${inter.className} flex flex-col justify-between min-h-screen`}
50+
className={`${inter.className} flex min-h-screen flex-col justify-between`}
5151
>
5252
{children}
5353
</body>

app/page.tsx

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
'use client';
1+
"use client";
22

3-
import Answer from '@/components/Answer';
4-
import Hero from '@/components/Hero';
5-
import InputArea from '@/components/InputArea';
6-
import SimilarTopics from '@/components/SimilarTopics';
7-
import Sources from '@/components/Sources';
8-
import Image from 'next/image';
9-
import { useRef, useState } from 'react';
10-
import { getAnswer, getSimilarQuestions, getSources } from './actions';
11-
import { readStreamableValue } from 'ai/rsc';
12-
import Header from '@/components/Header';
13-
import Footer from '@/components/Footer';
3+
import Answer from "@/components/Answer";
4+
import Hero from "@/components/Hero";
5+
import InputArea from "@/components/InputArea";
6+
import SimilarTopics from "@/components/SimilarTopics";
7+
import Sources from "@/components/Sources";
8+
import Image from "next/image";
9+
import { useRef, useState } from "react";
10+
import { getAnswer, getSimilarQuestions, getSources } from "./actions";
11+
import { readStreamableValue } from "ai/rsc";
12+
import Header from "@/components/Header";
13+
import Footer from "@/components/Footer";
1414

1515
export default function Home() {
16-
const [promptValue, setPromptValue] = useState('');
17-
const [question, setQuestion] = useState('');
16+
const [promptValue, setPromptValue] = useState("");
17+
const [question, setQuestion] = useState("");
1818
const [showResult, setShowResult] = useState(false);
19-
const [answer, setAnswer] = useState('');
19+
const [answer, setAnswer] = useState("");
2020
const [sources, setSources] = useState<{ name: string; url: string }[]>([]);
2121
const [similarQuestions, setSimilarQuestions] = useState<string[]>([]);
2222
const [loading, setLoading] = useState(false);
@@ -28,7 +28,7 @@ export default function Home() {
2828
setShowResult(true);
2929
setLoading(true);
3030
setQuestion(newQuestion);
31-
setPromptValue('');
31+
setPromptValue("");
3232

3333
await handleSourcesAndAnswer(newQuestion);
3434
await handleSimilarQuestions(newQuestion);
@@ -42,7 +42,7 @@ export default function Home() {
4242

4343
let answer = await getAnswer(question, sources);
4444

45-
let textContent = '';
45+
let textContent = "";
4646
for await (const delta of readStreamableValue(answer)) {
4747
textContent = textContent + delta;
4848
setAnswer(textContent);
@@ -56,17 +56,17 @@ export default function Home() {
5656

5757
const reset = () => {
5858
setShowResult(false);
59-
setPromptValue('');
60-
setQuestion('');
61-
setAnswer('');
59+
setPromptValue("");
60+
setQuestion("");
61+
setAnswer("");
6262
setSources([]);
6363
setSimilarQuestions([]);
6464
};
6565

6666
return (
6767
<>
6868
<Header />
69-
<main className='px-4 pb-4 h-full'>
69+
<main className="h-full px-4 pb-4">
7070
{!showResult && (
7171
<Hero
7272
promptValue={promptValue}
@@ -76,23 +76,23 @@ export default function Home() {
7676
)}
7777

7878
{showResult && (
79-
<div className='w-full grow h-full min-h-[68vh] flex flex-col justify-between '>
80-
<div className='w-full container space-y-2'>
81-
<div className='container space-y-2'>
82-
<div className='w-full flex items-start gap-3 container px-5 lg:px-10 pt-2'>
83-
<div className='w-fit flex gap-4 items-center'>
79+
<div className="flex h-full min-h-[68vh] w-full grow flex-col justify-between">
80+
<div className="container w-full space-y-2">
81+
<div className="container space-y-2">
82+
<div className="container flex w-full items-start gap-3 px-5 pt-2 lg:px-10">
83+
<div className="flex w-fit items-center gap-4">
8484
<Image
85-
src={'/img/message-question-circle.svg'}
86-
alt='message'
85+
src={"/img/message-question-circle.svg"}
86+
alt="message"
8787
width={30}
8888
height={30}
89-
className='size-[24px]'
89+
className="size-[24px]"
9090
/>
91-
<p className='text-black font-bold leading-[152%] uppercase'>
91+
<p className="pr-5 font-bold uppercase leading-[152%] text-black">
9292
Question:
9393
</p>
9494
</div>
95-
<div className='grow'>&quot;{question}&quot;</div>
95+
<div className="grow">&quot;{question}&quot;</div>
9696
</div>
9797
<>
9898
<Sources sources={sources} />
@@ -105,9 +105,9 @@ export default function Home() {
105105
</>
106106
</div>
107107

108-
<div className='pt-1 sm:pt-2' ref={chatContainerRef}></div>
108+
<div className="pt-1 sm:pt-2" ref={chatContainerRef}></div>
109109
</div>
110-
<div className='container px-4 lg:px-0'>
110+
<div className="container px-4 lg:px-0">
111111
<InputArea
112112
promptValue={promptValue}
113113
setPromptValue={setPromptValue}

0 commit comments

Comments
 (0)