Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace icons with svg components and more... #11

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Next Next commit
Let to const when able, sorted imports, syntax cleanup
  • Loading branch information
michaelwschultz committed Feb 3, 2025
commit 9e1c941c50cbc70073be7b751a0d1271af2cd9d0
4 changes: 2 additions & 2 deletions app/api/getChat/route.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {
TogetherAIStream,
TogetherAIStreamPayload,
type TogetherAIStreamPayload,
} from "@/utils/TogetherAIStream";

export const maxDuration = 60;

export async function POST(request: Request) {
let { messages } = await request.json();
const { messages } = await request.json();

try {
console.log("[getChat] Fetching answer stream from Together API");
Expand Down
15 changes: 10 additions & 5 deletions app/api/getParsedSources/route.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import { cleanedText, fetchWithTimeout } from "@/utils/utils";
import { Readability } from "@mozilla/readability";
import jsdom, { JSDOM } from "jsdom";
import { cleanedText, fetchWithTimeout } from "@/utils/utils";
import { NextResponse } from "next/server";

export const maxDuration = 30;

type Source = {
url: string;
name: string;
}

export async function POST(request: Request) {
let { sources } = await request.json();
const { sources } = await request.json();

console.log("[getAnswer] Fetching text from source URLS");
let finalResults = await Promise.all(
sources.map(async (result: any) => {
const finalResults = await Promise.all(
sources.map(async (result: Source) => {
try {
// Fetch the source URL, or abort if it's been 3 seconds
const response = await fetchWithTimeout(result.url);
Expand All @@ -20,7 +25,7 @@ export async function POST(request: Request) {

const doc = dom.window.document;
const parsed = new Readability(doc).parse();
let parsedContent = parsed
const parsedContent = parsed
? cleanedText(parsed.textContent)
: "Nothing found";

Expand Down
18 changes: 10 additions & 8 deletions app/api/getSources/route.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { NextResponse } from "next/server";
import { z } from "zod";

let excludedSites = ["youtube.com"];
let searchEngine: "bing" | "serper" = "serper";
const excludedSites = ["youtube.com"];
const searchEngine: "bing" | "serper" = "serper";

export async function POST(request: Request) {
let { question } = await request.json();
const { question } = await request.json();

const finalQuestion = `what is ${question}`;

if (searchEngine === "bing") {
const BING_API_KEY = process.env["BING_API_KEY"];
const BING_API_KEY = process.env.BING_API_KEY;
if (!BING_API_KEY) {
throw new Error("BING_API_KEY is required");
}
Expand Down Expand Up @@ -41,15 +41,17 @@ export async function POST(request: Request) {
const rawJSON = await response.json();
const data = BingJSONSchema.parse(rawJSON);

let results = data.webPages.value.map((result) => ({
const results = data.webPages.value.map((result) => ({
name: result.name,
url: result.url,
}));

return NextResponse.json(results);
// TODO: Figure out a way to remove certain results like YT
} else if (searchEngine === "serper") {
const SERPER_API_KEY = process.env["SERPER_API_KEY"];
}

if (searchEngine === "serper") {
const SERPER_API_KEY = process.env.SERPER_API_KEY;
if (!SERPER_API_KEY) {
throw new Error("SERPER_API_KEY is required");
}
Expand All @@ -74,7 +76,7 @@ export async function POST(request: Request) {

const data = SerperJSONSchema.parse(rawJSON);

let results = data.organic.map((result) => ({
const results = data.organic.map((result) => ({
name: result.title,
url: result.link,
}));
Expand Down
12 changes: 6 additions & 6 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import type { Metadata } from "next";
import { Montserrat } from "next/font/google";
import PlausibleProvider from "next-plausible";
import { Montserrat } from "next/font/google";
import "./globals.css";
import Image from "next/image";
import bgImage from "../public/new-bg.png";

const montserrat = Montserrat({ subsets: ["latin"] });

let title = "Llama Tutor – AI Personal Tutor";
let description = "Learn faster with our open source AI personal tutor";
let url = "https://llamatutor.com/";
let ogimage = "https://llamatutor.together.ai/og-image.png";
let sitename = "llamatutor.com";
const title = "Llama Tutor – AI Personal Tutor";
const description = "Learn faster with our open source AI personal tutor";
const url = "https://llamatutor.com/";
const ogimage = "https://llamatutor.together.ai/og-image.png";
const sitename = "llamatutor.com";

export const metadata: Metadata = {
metadataBase: new URL(url),
Expand Down
20 changes: 9 additions & 11 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
"use client";

import Footer from "@/components/Footer";
import Chat from "@/components/Chat";
import Header from "@/components/Header";
import Hero from "@/components/Hero";
import Sources from "@/components/Sources";
import { useState } from "react";
import { getSystemPrompt } from "@/utils/utils";
import {
type ParsedEvent,
type ReconnectInterval,
createParser,
ParsedEvent,
ReconnectInterval,
} from "eventsource-parser";
import { getSystemPrompt } from "@/utils/utils";
import Chat from "@/components/Chat";
import { useState } from "react";

export default function Home() {
const [inputValue, setInputValue] = useState("");
Expand Down Expand Up @@ -71,9 +70,8 @@ export default function Home() {
...prev.slice(0, -1),
{ ...lastMessage, content: lastMessage.content + text },
];
} else {
return [...prev, { role: "assistant", content: text }];
}
return [...prev, { role: "assistant", content: text }];
});
} catch (e) {
console.error(e);
Expand All @@ -98,11 +96,11 @@ export default function Home() {

async function handleSourcesAndChat(question: string) {
setIsLoadingSources(true);
let sourcesResponse = await fetch("/api/getSources", {
const sourcesResponse = await fetch("/api/getSources", {
method: "POST",
body: JSON.stringify({ question }),
});
let sources;
let sources = [];
if (sourcesResponse.ok) {
sources = await sourcesResponse.json();

Expand All @@ -116,7 +114,7 @@ export default function Home() {
method: "POST",
body: JSON.stringify({ sources }),
});
let parsedSources;
let parsedSources = [];
if (parsedSourcesRes.ok) {
parsedSources = await parsedSourcesRes.json();
}
Expand Down
8 changes: 4 additions & 4 deletions components/Chat.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import ReactMarkdown from "react-markdown";
import FinalInputArea from "./FinalInputArea";
import Image from "next/image";
import { useEffect, useRef, useState } from "react";
import ReactMarkdown from "react-markdown";
import simpleLogo from "../public/simple-logo.png";
import Image from "next/image";
import FinalInputArea from "./FinalInputArea";

export default function Chat({
messages,
Expand Down Expand Up @@ -38,7 +38,7 @@ export default function Chat({
}, [didScrollToBottom, messages]);

useEffect(() => {
let el = scrollableContainerRef.current;
const el = scrollableContainerRef.current;
if (!el) {
return;
}
Expand Down
4 changes: 2 additions & 2 deletions components/FinalInputArea.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, KeyboardEvent } from "react";
import type { FC, KeyboardEvent } from "react";
import TypeAnimation from "./TypeAnimation";
import Image from "next/image";

Expand All @@ -22,7 +22,7 @@ const FinalInputArea: FC<TInputAreaProps> = ({
handleChat,
}) => {
function onSubmit() {
let latestMessages = [...messages, { role: "user", content: promptValue }];
const latestMessages = [...messages, { role: "user", content: promptValue }];
setPromptValue("");
setMessages(latestMessages);
handleChat(latestMessages);
Expand Down
6 changes: 3 additions & 3 deletions components/TypeAnimation.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const TypeAnimation = () => {
return (
<div className="loader pb-1">
<span></span>
<span></span>
<span></span>
<span />
<span />
<span />
</div>
);
};
Expand Down