83 | // const articleText = $(".docs-content").text();
84 |
85 | let start = 0;
86 | while (start < articleText.length) {
87 | const end = start + docSize;
88 | const chunk = articleText.slice(start, end);
89 | documents.push({ url, body: chunk });
90 | start = end;
91 | }
92 | }
93 | return documents;
94 | }
95 |
--------------------------------------------------------------------------------
/pages/docs.tsx:
--------------------------------------------------------------------------------
1 | import { AnimatePresence, motion } from "framer-motion";
2 | import type { NextPage } from "next";
3 | import { useState } from "react";
4 | import { Toaster, toast } from "react-hot-toast";
5 | import { v4 as uuidv4 } from 'uuid';
6 | import LoadingDots from "@/components/LoadingDots";
7 | import ResizablePanel from "@/components/ResizablePanel";
8 | import MetaTags from "@/components/MetaTags";
9 | import { ReactNode } from "react";
10 | import { PageMeta } from "../types";
11 | import MarkdownRenderer from "@/components/MarkdownRenderer";
12 |
13 |
14 | interface Props {
15 | children: ReactNode;
16 | meta?: PageMeta;
17 | }
18 |
19 | const DocsPage: NextPage
= ({ children, meta: pageMeta }: Props) => {
20 | const [loading, setLoading] = useState(false);
21 | const [userQ, setUserQ] = useState("");
22 | const [answer, setAanswer] = useState("");
23 |
24 | console.log("Streamed response: ", answer);
25 |
26 | const question = userQ;
27 |
28 | const generateAnswer = async (e: any) => {
29 | e.preventDefault();
30 | if (!userQ) {
31 | return toast.error("Please enter a question!");
32 | }
33 |
34 | setAanswer("");
35 | setLoading(true);
36 | const response = await fetch("/api/docs", {
37 | method: "POST",
38 | headers: {
39 | "Content-Type": "application/json"
40 | },
41 | body: JSON.stringify({
42 | question
43 | })
44 | });
45 | console.log("Edge function returned.");
46 |
47 | if (!response.ok) {
48 | throw new Error(response.statusText);
49 | }
50 |
51 | // This data is a ReadableStream
52 | const data = response.body;
53 | if (!data) {
54 | return;
55 | }
56 |
57 | const reader = data.getReader();
58 | const decoder = new TextDecoder();
59 | let done = false;
60 |
61 | while (!done) {
62 | const { value, done: doneReading } = await reader.read();
63 | done = doneReading;
64 | const chunkValue = decoder.decode(value);
65 | setAanswer((prev) => prev + chunkValue);
66 | }
67 |
68 | setLoading(false);
69 | };
70 |
71 |
72 | return (
73 | <>
74 |
80 |
81 |
82 |
83 |
84 |
85 | Ask me anything* about web development!
86 |
87 |
202 |
203 |
204 | >
205 | );
206 | };
207 |
208 | export default DocsPage;
209 |
--------------------------------------------------------------------------------
/pages/embeddings.tsx:
--------------------------------------------------------------------------------
1 | import { NextPage } from "next";
2 | import { useState } from "react";
3 |
4 |
5 | const Embeddings: NextPage = () => {
6 | const [urls, setUrls] = useState([]);
7 | const [loading, setLoading] = useState(false);
8 |
9 | const handleSubmit = async (e: React.FormEvent) => {
10 | e.preventDefault();
11 | setLoading(true);
12 |
13 | const response = await fetch("/api/generate-embeddings", {
14 | method: "POST",
15 | headers: { "Content-Type": "application/json" },
16 | body: JSON.stringify({ urls })
17 | });
18 |
19 | setLoading(false);
20 |
21 | if (!response.ok) {
22 | // Handle error
23 | }
24 | };
25 |
26 | return (
27 |
28 |
29 | Generate embeddings
30 |
31 |
32 | Paste a list of URLs below to geneate embeddings using the OpenAI API, and add the embeddings to the Supabase embeddings table.
33 |
34 |
49 | {loading &&
Loading...
}
50 |
51 | );
52 | };
53 |
54 | export default Embeddings;
55 |
--------------------------------------------------------------------------------
/pages/index.tsx:
--------------------------------------------------------------------------------
1 | // pages/index.tsx
2 |
3 | import { NextPage } from "next";
4 | import Link from "next/link";
5 |
6 | const HomePage: NextPage = () => {
7 | return (
8 |
9 |
10 |
11 | Domain-specific Chat GPT-3 Starter App
12 |
13 |
14 | - Create Embeddings
15 | - Search
16 |
17 |
18 |
19 |
20 | );
21 | };
22 |
23 | export default HomePage;
24 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = {
3 | plugins: {
4 | tailwindcss: {},
5 | autoprefixer: {}
6 | }
7 | };
--------------------------------------------------------------------------------
/public/bot/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/android-chrome-192x192.png
--------------------------------------------------------------------------------
/public/bot/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/android-chrome-512x512.png
--------------------------------------------------------------------------------
/public/bot/apple-touch-icon-114x114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/apple-touch-icon-114x114.png
--------------------------------------------------------------------------------
/public/bot/apple-touch-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/apple-touch-icon-120x120.png
--------------------------------------------------------------------------------
/public/bot/apple-touch-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/apple-touch-icon-144x144.png
--------------------------------------------------------------------------------
/public/bot/apple-touch-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/apple-touch-icon-152x152.png
--------------------------------------------------------------------------------
/public/bot/apple-touch-icon-167x167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/apple-touch-icon-167x167.png
--------------------------------------------------------------------------------
/public/bot/apple-touch-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/apple-touch-icon-180x180.png
--------------------------------------------------------------------------------
/public/bot/apple-touch-icon-57x57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/apple-touch-icon-57x57.png
--------------------------------------------------------------------------------
/public/bot/apple-touch-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/apple-touch-icon-60x60.png
--------------------------------------------------------------------------------
/public/bot/apple-touch-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/apple-touch-icon-72x72.png
--------------------------------------------------------------------------------
/public/bot/apple-touch-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/apple-touch-icon-76x76.png
--------------------------------------------------------------------------------
/public/bot/bot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/bot.png
--------------------------------------------------------------------------------
/public/bot/bot.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/public/bot/docs-og.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/docs-og.png
--------------------------------------------------------------------------------
/public/bot/favicon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/favicon-128x128.png
--------------------------------------------------------------------------------
/public/bot/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/favicon-16x16.png
--------------------------------------------------------------------------------
/public/bot/favicon-196x196.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/favicon-196x196.png
--------------------------------------------------------------------------------
/public/bot/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/favicon-32x32.png
--------------------------------------------------------------------------------
/public/bot/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/favicon-96x96.png
--------------------------------------------------------------------------------
/public/bot/mstile-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/mstile-144x144.png
--------------------------------------------------------------------------------
/public/bot/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/mstile-150x150.png
--------------------------------------------------------------------------------
/public/bot/mstile-310x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/mstile-310x150.png
--------------------------------------------------------------------------------
/public/bot/mstile-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/mstile-310x310.png
--------------------------------------------------------------------------------
/public/bot/mstile-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/mstile-70x70.png
--------------------------------------------------------------------------------
/public/bot/og.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/bot/og.png
--------------------------------------------------------------------------------
/public/images/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gannonh/chatgpt-pgvector/8fff33138c03684626ee7094706d2a61262fecb8/public/images/background.png
--------------------------------------------------------------------------------
/styles/chrome-bug.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Chrome has a bug with transitions on load since 2012!
3 | *
4 | * To prevent a "pop" of content, you have to disable all transitions until
5 | * the page is done loading.
6 | *
7 | * https://lab.laukstein.com/bug/input
8 | * https://twitter.com/timer150/status/1345217126680899584
9 | */
10 | body.loading * {
11 | transition: none !important;
12 | }
13 |
--------------------------------------------------------------------------------
/styles/loading-dots.module.css:
--------------------------------------------------------------------------------
1 | .loading {
2 | display: inline-flex;
3 | align-items: center;
4 | }
5 |
6 | .loading .spacer {
7 | margin-right: 2px;
8 | }
9 |
10 | .loading span {
11 | animation-name: blink;
12 | animation-duration: 1.4s;
13 | animation-iteration-count: infinite;
14 | animation-fill-mode: both;
15 | width: 5px;
16 | height: 5px;
17 | border-radius: 50%;
18 | display: inline-block;
19 | margin: 0 1px;
20 | }
21 |
22 | .loading span:nth-of-type(2) {
23 | animation-delay: 0.2s;
24 | }
25 |
26 | .loading span:nth-of-type(3) {
27 | animation-delay: 0.4s;
28 | }
29 |
30 | .loading2 {
31 | display: inline-flex;
32 | align-items: center;
33 | }
34 |
35 | .loading2 .spacer {
36 | margin-right: 2px;
37 | }
38 |
39 | .loading2 span {
40 | animation-name: blink;
41 | animation-duration: 1.4s;
42 | animation-iteration-count: infinite;
43 | animation-fill-mode: both;
44 | width: 4px;
45 | height: 4px;
46 | border-radius: 50%;
47 | display: inline-block;
48 | margin: 0 1px;
49 | }
50 |
51 | .loading2 span:nth-of-type(2) {
52 | animation-delay: 0.2s;
53 | }
54 |
55 | .loading2 span:nth-of-type(3) {
56 | animation-delay: 0.4s;
57 | }
58 |
59 | @keyframes blink {
60 | 0% {
61 | opacity: 0.2;
62 | }
63 | 20% {
64 | opacity: 1;
65 | }
66 | 100% {
67 | opacity: 0.2;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/styles/main.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | const defaultTheme = require("tailwindcss/defaultTheme");
2 |
3 | module.exports = {
4 | content: [
5 | "./pages/**/*.{js,ts,jsx,tsx}",
6 | "./components/**/*.{js,ts,jsx,tsx}"
7 | ],
8 |
9 | plugins: [require("daisyui")],
10 | // daisyUI config (optional)
11 | daisyui: {
12 | styled: true,
13 | themes: [
14 | {
15 | mytheme: {
16 | primary: "#0EA5E9",
17 |
18 | secondary: "#0369A1",
19 |
20 | accent: "#D946EF",
21 |
22 | neutral: "#1E293B",
23 |
24 | "base-100": "#0F172A",
25 |
26 | info: "#0CA5E9",
27 |
28 | success: "#2DD4BF",
29 |
30 | warning: "#F4BF50",
31 |
32 | error: "#FB7085"
33 | }
34 | }
35 | ],
36 | base: true,
37 | utils: true,
38 | logs: true,
39 | rtl: false,
40 | prefix: "",
41 | darkTheme: "night",
42 | },
43 |
44 | theme: {
45 | extend: {
46 | fontFamily: {
47 | sans: ["Inter var", ...defaultTheme.fontFamily.sans]
48 | }
49 | }
50 | }
51 | };
52 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "strict": true,
12 | "forceConsistentCasingInFileNames": true,
13 | "noEmit": true,
14 | "esModuleInterop": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "jsx": "preserve",
20 | "baseUrl": ".",
21 | "paths": {
22 | "@/components/*": ["components/*"],
23 | "@/utils/*": ["utils/*"],
24 | "@/styles/*": ["styles/*"],
25 | "@/images/*": ["public/images/*"],
26 | "@/data/*": ["data/*"],
27 | "@/services/*": ["services/*"],
28 | "@/lib/*": ["lib/*"]
29 |
30 | },
31 | "incremental": true
32 | },
33 | "include": [
34 | "next-env.d.ts",
35 | "**/*.ts",
36 | "**/*.tsx"
37 | ],
38 | "exclude": [
39 | "node_modules",
40 | "supabse"
41 | ]
42 | }
43 |
--------------------------------------------------------------------------------
/types.ts:
--------------------------------------------------------------------------------
1 | export interface PageMeta {
2 | title: string;
3 | description: string;
4 | cardImage: string;
5 | }
--------------------------------------------------------------------------------
/utils/OpenAIStream.ts:
--------------------------------------------------------------------------------
1 | import {
2 | createParser,
3 | ParsedEvent,
4 | ReconnectInterval,
5 | } from "eventsource-parser";
6 |
7 | export interface OpenAIStreamPayload {
8 | model: string;
9 | messages: { role: string; content: string }[];
10 | temperature: number;
11 | top_p: number;
12 | frequency_penalty: number;
13 | presence_penalty: number;
14 | max_tokens: number;
15 | stream: boolean;
16 | n: number;
17 | }
18 |
19 | export async function OpenAIStream(payload: OpenAIStreamPayload) {
20 | const encoder = new TextEncoder();
21 | const decoder = new TextDecoder();
22 |
23 | let counter = 0;
24 |
25 | const apiURL = process.env.OPENAI_PROXY == "" ? "https://api.openai.com" : process.env.OPENAI_PROXY;
26 |
27 | const res = await fetch(apiURL + "/v1/chat/completions", {
28 | headers: {
29 | "Content-Type": "application/json",
30 | Authorization: `Bearer ${process.env.OPENAI_API_KEY ?? ""}`,
31 | },
32 | method: "POST",
33 | body: JSON.stringify(payload),
34 | });
35 |
36 | const stream = new ReadableStream({
37 | async start(controller) {
38 | // callback
39 | function onParse(event: ParsedEvent | ReconnectInterval) {
40 | if (event.type === "event") {
41 | const data = event.data;
42 | if (data === "[DONE]") {
43 | controller.close();
44 | return;
45 | }
46 | try {
47 | const json = JSON.parse(data);
48 | // console.log("JSON.parse(data): ", json);
49 | const content = json.choices[0].delta.content;
50 | // console.log("content: ", content);
51 | const queue = encoder.encode(content);
52 | controller.enqueue(queue);
53 | counter++;
54 | } catch (e) {
55 | // maybe parse error
56 | controller.error(e);
57 | }
58 | }
59 | }
60 |
61 | // stream response (SSE) from OpenAI may be fragmented into multiple chunks
62 | // this ensures we properly read chunks and invoke an event for each SSE event stream
63 | const parser = createParser(onParse);
64 | // https://web.dev/streams/#asynchronous-iteration
65 | for await (const chunk of res.body as any) {
66 | parser.feed(decoder.decode(chunk));
67 | }
68 | },
69 | });
70 |
71 | return stream;
72 | }
73 |
--------------------------------------------------------------------------------