Skip to content

Commit

Permalink
Working files
Browse files Browse the repository at this point in the history
  • Loading branch information
D9J9V committed Sep 5, 2024
1 parent 6941217 commit cc50a82
Show file tree
Hide file tree
Showing 19 changed files with 771 additions and 0 deletions.
11 changes: 11 additions & 0 deletions packages/nextjs/drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Config } from "drizzle-kit";
import { env } from "./src/lib/env.mjs";

export default {
schema: "./lib/db/schema",
dialect: "postgresql",
out: "./lib/db/migrations",
dbCredentials: {
url: env.DATABASE_URL,
},
} satisfies Config;
112 changes: 112 additions & 0 deletions packages/nextjs/src/app/_components/icons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
export const VercelIcon = ({ size = 17 }) => {
return (
<svg
height={size}
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M8 1L16 15H0L8 1Z"
fill="currentColor"
></path>
</svg>
);
};

export const InformationIcon = ({ size = 17 }) => {
return (
<svg
height={size}
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M8 14.5C11.5899 14.5 14.5 11.5899 14.5 8C14.5 4.41015 11.5899 1.5 8 1.5C4.41015 1.5 1.5 4.41015 1.5 8C1.5 11.5899 4.41015 14.5 8 14.5ZM8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16ZM6.25 7H7H7.74999C8.30227 7 8.74999 7.44772 8.74999 8V11.5V12.25H7.24999V11.5V8.5H7H6.25V7ZM8 6C8.55229 6 9 5.55228 9 5C9 4.44772 8.55229 4 8 4C7.44772 4 7 4.44772 7 5C7 5.55228 7.44772 6 8 6Z"
fill="currentColor"
></path>
</svg>
);
};

export const LoadingIcon = () => {
return (
<svg
height="16"
strokeLinejoin="round"
viewBox="0 0 16 16"
width="16"
style={{ color: "currentcolor" }}
>
<g clipPath="url(#clip0_2393_1490)">
<path d="M8 0V4" stroke="currentColor" strokeWidth="1.5"></path>
<path
opacity="0.5"
d="M8 16V12"
stroke="currentColor"
strokeWidth="1.5"
></path>
<path
opacity="0.9"
d="M3.29773 1.52783L5.64887 4.7639"
stroke="currentColor"
strokeWidth="1.5"
></path>
<path
opacity="0.1"
d="M12.7023 1.52783L10.3511 4.7639"
stroke="currentColor"
strokeWidth="1.5"
></path>
<path
opacity="0.4"
d="M12.7023 14.472L10.3511 11.236"
stroke="currentColor"
strokeWidth="1.5"
></path>
<path
opacity="0.6"
d="M3.29773 14.472L5.64887 11.236"
stroke="currentColor"
strokeWidth="1.5"
></path>
<path
opacity="0.2"
d="M15.6085 5.52783L11.8043 6.7639"
stroke="currentColor"
strokeWidth="1.5"
></path>
<path
opacity="0.7"
d="M0.391602 10.472L4.19583 9.23598"
stroke="currentColor"
strokeWidth="1.5"
></path>
<path
opacity="0.3"
d="M15.6085 10.4722L11.8043 9.2361"
stroke="currentColor"
strokeWidth="1.5"
></path>
<path
opacity="0.8"
d="M0.391602 5.52783L4.19583 6.7639"
stroke="currentColor"
strokeWidth="1.5"
></path>
</g>
<defs>
<clipPath id="clip0_2393_1490">
<rect width="16" height="16" fill="white"></rect>
</clipPath>
</defs>
</svg>
);
};
38 changes: 38 additions & 0 deletions packages/nextjs/src/app/_components/oracle/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as React from "react";

const buttonVariants = {
default: "btn btn-primary",
destructive: "btn btn-error",
outline: "btn btn-outline",
secondary: "btn btn-secondary",
ghost: "btn btn-ghost",
link: "btn btn-link",
};

const sizeVariants = {
default: "btn-md",
sm: "btn-sm",
lg: "btn-lg",
icon: "btn-square btn-md",
};

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: keyof typeof buttonVariants;
size?: keyof typeof sizeVariants;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant = "default", size = "default", ...props }, ref) => {
return (
<button
className={`btn ${buttonVariants[variant]} ${sizeVariants[size]} ${className || ""}`}
ref={ref}
{...props}
/>
);
},
);
Button.displayName = "Button";

export { Button, buttonVariants };
25 changes: 25 additions & 0 deletions packages/nextjs/src/app/_components/oracle/input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as React from "react";

import { cn } from "@/lib/utils";

export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}

const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
"flex h-10 w-full rounded-md bg-background px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground outline-none disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
ref={ref}
{...props}
/>
);
},
);
Input.displayName = "Input";

export { Input };
16 changes: 16 additions & 0 deletions packages/nextjs/src/app/_components/oracle/label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";

const Label = React.forwardRef<
HTMLLabelElement,
React.LabelHTMLAttributes<HTMLLabelElement>
>(({ className, ...props }, ref) => (
<label
ref={ref}
className={`text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 ${className}`}
{...props}
/>
));

Label.displayName = "Label";

export { Label };
91 changes: 91 additions & 0 deletions packages/nextjs/src/app/api/chat/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { createResource } from "@/lib/actions/resources";
import { findRelevantContent } from "@/lib/ai/embeddings";
import { openai } from "@ai-sdk/openai";
import { convertToCoreMessages, generateObject, streamText, tool } from "ai";
import { z } from "zod";

// Allow streaming responses up to 30 seconds
export const maxDuration = 30;

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

const result = await streamText({
model: openai("gpt-4o"),
messages: convertToCoreMessages(messages),
system: `You are a helpful assistant acting as the users' second brain.
Use tools on every request.
Be sure to getInformation from your knowledge base before answering any questions.
If the user presents infromation about themselves, use the addResource tool to store it.
If a response requires multiple tools, call one tool after another without responding to the user.
If a response requires information from an additional tool to generate a response, call the appropriate tools in order before responding to the user.
ONLY respond to questions using information from tool calls.
if no relevant information is found in the tool calls, respond, "Sorry, I don't know."
Be sure to adhere to any instructions in tool calls ie. if they say to responsd like "...", do exactly that.
If the relevant information is not a direct match to the users prompt, you can be creative in deducing the answer.
Keep responses short and concise. Answer in a single sentence where possible.
If you are unsure, use the getInformation tool and you can use common sense to reason based on the information you do have.
Use your abilities as a reasoning machine to answer questions based on the information you do have.
`,
tools: {
addResource: tool({
description: `add a resource to your knowledge base.
If the user provides a random piece of knowledge unprompted, use this tool without asking for confirmation.`,
parameters: z.object({
content: z
.string()
.describe("the content or resource to add to the knowledge base"),
}),
execute: async ({ content }) => createResource({ content }),
}),
getInformation: tool({
description: `get information from your knowledge base to answer questions.`,
parameters: z.object({
question: z.string().describe("the users question"),
similarQuestions: z.array(z.string()).describe("keywords to search"),
}),
execute: async ({ similarQuestions }) => {
const results = await Promise.all(
similarQuestions.map(
async (question) => await findRelevantContent(question),
),
);
// Flatten the array of arrays and remove duplicates based on 'name'
const uniqueResults = Array.from(
new Map(results.flat().map((item) => [item?.name, item])).values(),
);
return uniqueResults;
},
}),
understandQuery: tool({
description: `understand the users query. use this tool on every prompt.`,
parameters: z.object({
query: z.string().describe("the users query"),
toolsToCallInOrder: z
.array(z.string())
.describe(
"these are the tools you need to call in the order necessary to respond to the users query",
),
}),
execute: async ({ query }) => {
const { object } = await generateObject({
model: openai("gpt-4o"),
system:
"You are a query understanding assistant. Analyze the user query and generate similar questions.",
schema: z.object({
questions: z
.array(z.string())
.max(3)
.describe("similar questions to the user's query. be concise."),
}),
prompt: `Analyze this query: "${query}". Provide the following:
3 similar questions that could help answer the user's query`,
});
return object.questions;
},
}),
},
});

return result.toDataStreamResponse();
}
Empty file.
Loading

0 comments on commit cc50a82

Please sign in to comment.