diff --git a/packages/nextjs/app/api/newHack/route.ts b/packages/nextjs/app/api/newHack/route.ts index 0e88fed..3b3ad7b 100644 --- a/packages/nextjs/app/api/newHack/route.ts +++ b/packages/nextjs/app/api/newHack/route.ts @@ -97,6 +97,7 @@ async function generateHackathonProposal(hackathonApp: HackathonEntry) { innovationScore: number; funScore: number; evaluationRemarks: string; + codeSnippets: CodeEntry[]; } `, }, diff --git a/packages/nextjs/app/api/newUpdate/route.ts b/packages/nextjs/app/api/newUpdate/route.ts new file mode 100644 index 0000000..dd534a8 --- /dev/null +++ b/packages/nextjs/app/api/newUpdate/route.ts @@ -0,0 +1,157 @@ +import { NextResponse } from "next/server"; +// Assuming we've defined or imported types for the Hackathon Application +// + +import type { AIEvaluation, HackathonEntry } from "~~/types/dbSchema"; + +// Assumed environme +import { MongoDBAtlasVectorSearch, VectorStoreIndex, storageContextFromDefaults, Document } from "llamaindex"; +import { MongoClient } from "mongodb"; + +import { ChatMessage, MessageContent, OpenAI, serviceContextFromDefaults } from "llamaindex"; +import { createChatEngine } from "../chat/engine"; + +const url = 'mongodb+srv://At0x:r8MzJR2r4A1xlMOA@cluster1.upfglfg.mongodb.net/?retryWrites=true&w=majority' + +const client = new MongoClient(url); +await client.connect(); +// Database Name + +async function llamaindex(payload: string, id: string) { + const vectorStore = new MongoDBAtlasVectorSearch({ + mongodbClient: client, + dbName: "aiUniverse", + collectionName: "hackerIndex", // this is where your embeddings will be stored + indexName: "hacker_index", // this is the name of the index you will need to create + }); + + // now create an index from all the Documents and store them in Atlas + const storageContext = await storageContextFromDefaults({ vectorStore }); + + const essay = payload; + + + // Create Document object with essay + const document = new Document({ text: essay, id_: id }); + + // Split text and create embeddings. Store them in a VectorStoreIndex + await VectorStoreIndex.fromDocuments([document], { storageContext }); + + console.log( + `Successfully created embeddings in the MongoDB collection`, + ); +} + +// Revised function suited for hackathon application data +async function generateHackathonProposal(hackathonApp: HackathonEntry) { + const messages: ChatMessage[] = [ + { + role: "system", + content: `You are an AI consultant specializing in hackathon project conceptualization. Given a project name, problem statement, solution description, and technology stack, Ponder on the different aspects of the presented project and give a score for each domain. Use the evaluationRemarks to appraise the projects and compare them to each other. Suggest collaboration opportunities, code snippets or advice that may help hackers. Reply in JSON format using the AIEvaluation type.`, + }, + { + role: "assistant", + content: ` + type AIEvaluation = { + coherenceScore: number; + feasabilityScore: number; + innovationScore: number; + funScore: number; + evaluationRemarks: string; + codeSnippets: CodeEntry[]; + } + + type CodeEntry = { + code: string; + comment: string; + language: string; + } + + `, + }, + { + role: "user", + content: `Review the hackathon update, assign scores and provide feedback in the evaluation remarks. + _id: ${hackathonApp._id}; + projectName: ${hackathonApp.hack.projectName}; + problemStatement: ${hackathonApp.hack.problemStatement} + solutionDescription: ${hackathonApp.hack.solutionDescription} + technologyStack: ${hackathonApp.hack.technologyStack.join(", ")} +previousEvaluations: ${hackathonApp.eval.join(", ") ?? "No previous evaluation"} + `, + }, + ]; + + const llm = new OpenAI({ + model: (process.env.MODEL as any) ?? "gpt-4-0125-preview", + maxTokens: 512, + additionalChatOptions: { response_format: { type: "json_object" } }, + }); + + const serviceContext = serviceContextFromDefaults({ + llm, + chunkSize: 512, + chunkOverlap: 20, + }); + + + const chatEngine = await createChatEngine( + serviceContext, + ); + if (!chatEngine) return NextResponse.json({ error: "datasource is required in the request body" }, { status: 400 }); + + // Convert message content from Vercel/AI format to LlamaIndex/OpenAI format + + + const response = await chatEngine.chat({ + message: "Evaluate the hackathon entry and provide scores and remarks.", + chatHistory: messages, + }); + + console.log(JSON.parse(response.response)) + + const rawOutput: AIEvaluation = JSON.parse(response.response); + return rawOutput; +} + +// Example usage for POST handler or another part of your application +export async function POST(request: Request) { + const hackathonApp = await request.json(); // Assuming the request body is properly formatted + const enhancedProposal = await generateHackathonProposal(hackathonApp); + + + hackathonApp.eval.push(enhancedProposal); + + const stringifiedHackathonApp = JSON.stringify(hackathonApp); + + + // Proceed with storing the enhanced proposal in MongoDB or returning it in the response + // + const db = client.db("aiUniverse"); // Connect to the database + const hackCodex = db.collection('hackerUniverse'); // + + // assumed input + + llamaindex(JSON.stringify(stringifiedHackathonApp), hackathonApp.projectId);//should we modify this id? + + + + await hackCodex.updateOne( + { + _id: hackathonApp._id, + address: hackathonApp.address, + hack: hackathonApp.hack + }, + { + $addToSet: { + eval: enhancedProposal, + progressUpdates: hackathonApp.progressUpdates[hackathonApp.progressUpdates.length - 1] + } + }, + { upsert: true },// this creates new document if none match the filter + ); + + // Implementation depends on application requirements. + // + return NextResponse.json(hackathonApp, { status: 200 }) +} diff --git a/packages/nextjs/app/hackathon.ts b/packages/nextjs/app/hackathon.ts index 58120cb..b003f30 100644 --- a/packages/nextjs/app/hackathon.ts +++ b/packages/nextjs/app/hackathon.ts @@ -1,105 +1,123 @@ "use client"; import { toast } from "react-hot-toast"; -import { - AIEvaluation, - HackathonEntry, - HackathonProjectAttributes, - ProgressUpdate, - TeamMember, -} from "~~/types/dbSchema"; +import { AIEvaluation, HackathonEntry, TeamMember, HackathonProjectAttributes, ProgressUpdate } from "~~/types/dbSchema"; export class hackathonEntry { - address: string; - _id: string; - hack: HackathonProjectAttributes; - progressUpdates: ProgressUpdate[]; - eval: AIEvaluation[]; - teamMembers: TeamMember[]; - - constructor( - address: string, - projectId: string, - attributes: Partial, - teamMembers?: TeamMember[], - evals?: AIEvaluation[], - progressUpdates?: ProgressUpdate[], - ) { - this.address = address; - this._id = projectId; - this.hack = { - projectName: attributes.projectName ?? "", - problemStatement: attributes.problemStatement ?? "", - solutionDescription: attributes.solutionDescription ?? "", - technologyStack: attributes.technologyStack ?? [], - implementationDescription: attributes.implementationDescription ?? "", - }; - (this.teamMembers = teamMembers ?? []), (this.eval = evals ?? []); - this.progressUpdates = progressUpdates ?? []; - } - - // Function to add a member to the project - addTeamMember(member: TeamMember): void { - this.teamMembers.push(member); - } - // Function to update the coherence score and evaluation remarks - evaluateProject(aiEval: AIEvaluation): void { - this.eval.push(aiEval); - } - // Function to update the progress score and evaluation remarks - updateProject(update: ProgressUpdate): void { - this.progressUpdates.push(update); - } - - // Get project information - getProjectInfo(): HackathonEntry { - return { - address: this.address, - _id: this._id, - hack: this.hack, - teamMembers: this.teamMembers, - progressUpdates: this.progressUpdates, - eval: this.eval, - }; - } + address: string; + _id: string; + hack: HackathonProjectAttributes; + progressUpdates: ProgressUpdate[]; + eval: AIEvaluation[]; + teamMembers: TeamMember[]; + + constructor( + address: string, + projectId: string, + attributes: Partial, + teamMembers?: TeamMember[], + evals?: AIEvaluation[], + progressUpdates?: ProgressUpdate[], + ) { + this.address = address; + this._id = projectId; + this.hack = { + projectName: attributes.projectName ?? "", + problemStatement: attributes.problemStatement ?? "", + solutionDescription: attributes.solutionDescription ?? "", + technologyStack: attributes.technologyStack ?? [], + implementationDescription: attributes.implementationDescription ?? "", + }; + this.teamMembers = teamMembers ?? [], + this.eval = evals ?? []; + this.progressUpdates = progressUpdates ?? []; + } + + // Function to add a member to the project + addTeamMember(member: TeamMember): void { + this.teamMembers.push(member); + } + // Function to update the coherence score and evaluation remarks + evaluateProject(aiEval: AIEvaluation): void { + this.eval.push(aiEval); + } + // Function to update the progress score and evaluation remarks + updateProject(update: ProgressUpdate): void { + this.progressUpdates.push(update); + } + + // Get project information + getProjectInfo(): HackathonEntry { + return { + address: this.address, + _id: this._id, + hack: this.hack, + teamMembers: this.teamMembers, + progressUpdates: this.progressUpdates, + eval: this.eval + }; + } } + export async function createHackathonEntry(hackathonProject: HackathonEntry): Promise { - // Mimic an asynchronous operation, for example, saving to a database - const newProject = new hackathonEntry( - hackathonProject.address, - hackathonProject._id, - hackathonProject.hack, - hackathonProject.teamMembers, - hackathonProject.eval, - hackathonProject.progressUpdates, - ); - const response = await fetch("/api/newHack", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(newProject.getProjectInfo()), - }); - const parsed: HackathonEntry = await response.json(); - - console.log("rawResponse", parsed); - - newProject.evaluateProject(parsed.eval[parsed.eval.length - 1]); - toast.success(`"${parsed} has been created"`); // Include database save operation here if needed - return newProject; + // Mimic an asynchronous operation, for example, saving to a database + const newProject = new hackathonEntry( + hackathonProject.address, + hackathonProject._id, + hackathonProject.hack, + hackathonProject.teamMembers, + hackathonProject.eval, + hackathonProject.progressUpdates); + const response = await fetch("/api/newHack", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(newProject.getProjectInfo()), + }); + const parsed: HackathonEntry = await response.json(); + + + console.log("rawResponse", parsed); + + newProject.evaluateProject(parsed.eval[parsed.eval.length - 1]) + toast.success(`"${parsed} has been created"`); // Include database save operation here if needed + return newProject; } -export async function updateHackathonEntry(hackathonProject: HackathonEntry): Promise { - // This function would be implemented to find a project by its ID and then add a team member - // Include database update operation here if needed +export async function updateHackathonEntry(hackathonProject: HackathonEntry): Promise { + // Mimic an asynchronous operation, for example, saving to a database + const newProject = new hackathonEntry( + hackathonProject.address, + hackathonProject._id, + hackathonProject.hack, + hackathonProject.teamMembers, + hackathonProject.eval, + hackathonProject.progressUpdates); + const response = await fetch("/api/newUpdate", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(newProject.getProjectInfo()), + }); + const parsed: HackathonEntry = await response.json(); + + + console.log("rawResponse", parsed); + + newProject.evaluateProject(parsed.eval[parsed.eval.length - 1]) + toast.success(`"${parsed} has been created"`); // Include database save operation here if needed + return newProject; } + export async function evaluateAndScoreEntry( - projectId: string, - coherenceScore: number, - evaluationRemarks: string, + projectId: string, + coherenceScore: number, + evaluationRemarks: string, ): Promise { - // This function would be implemented to find a project by its ID and update its score and evaluations - // Include database update operation here if needed + // This function would be implemented to find a project by its ID and update its score and evaluations + // Include database update operation here if needed } diff --git a/packages/nextjs/app/page.tsx b/packages/nextjs/app/page.tsx index 128be95..4d04ddb 100644 --- a/packages/nextjs/app/page.tsx +++ b/packages/nextjs/app/page.tsx @@ -5,7 +5,7 @@ import { useEffect, useState } from "react"; import type { NextPage } from "next"; import { toast } from "react-hot-toast"; import { useAccount } from 'wagmi'; -import { createHackathonEntry, hackathonEntry } from "~~/app/hackathon"; import { ChartContainer, BarChart } from "@mui/x-charts"; +import { createHackathonEntry, hackathonEntry, updateHackathonEntry } from "~~/app/hackathon"; import { ChartContainer, BarChart } from "@mui/x-charts"; import ChatSection from "./components/chat-section"; import { HackathonEntry, HackathonProjectAttributes, AIEvaluation, TeamMember, ProgressUpdate, CodeEntry } from "~~/types/dbSchema"; import { useSigner } from "~~/utils/wagmi-utils"; @@ -39,7 +39,7 @@ const Home: NextPage = () => { losses: "", gamePlan: "", actionItems: [], - code: [] as CodeEntry[], + codeSnippets: [] as CodeEntry[], }); const [myProject, setMyProject] = useState({} as HackathonEntry); const [techInput, setTechInput] = useState(""); @@ -174,7 +174,7 @@ const Home: NextPage = () => { try { // Validate or prepare data as needed before submission entry.progressUpdates?.push(updateData); - const hackEntry: hackathonEntry = await createHackathonEntry(entry); + const hackEntry: hackathonEntry = await updateHackathonEntry(entry); const res = hackEntry.getProjectInfo() setEntry(res); toast(`Project Information: ${JSON.stringify(res)}`); @@ -218,7 +218,7 @@ const Home: NextPage = () => { const newCode = { code: codeInput, comment: codeComment, language: codeLanguage }; // Simplify for demonstration setUpdateData({ ...updateData, - code: [...updateData.code, newCode], + codeSnippets: [...updateData.codeSnippets, newCode], }); setCodeInput(""); setCodeComment(""); @@ -487,6 +487,10 @@ const Home: NextPage = () => {
  • Evaluation Comments: {entry?.eval[evalIndex]?.evaluationRemarks}
  • +
  • Code Snippets: {entry?.eval[evalIndex]?.codeSnippets?.map((snippet: CodeEntry, i: number) => (<> +
  • {snippet.code}
  • +
  • {snippet.comment}
  • + ))}
  • Fun Score: {entry?.eval[evalIndex]?.funScore}
  • Innovation Score: {entry?.eval[evalIndex]?.innovationScore}
  • Feasibility: {entry?.eval[evalIndex]?.feasabilityScore}
  • diff --git a/packages/nextjs/types/dbSchema.ts b/packages/nextjs/types/dbSchema.ts index 58c0902..3c300b1 100644 --- a/packages/nextjs/types/dbSchema.ts +++ b/packages/nextjs/types/dbSchema.ts @@ -1,46 +1,47 @@ export type HackathonEntry = { - address: string; - _id: string; - hack: HackathonProjectAttributes; - teamMembers: TeamMember[]; - eval: AIEvaluation[]; - progressUpdates: ProgressUpdate[]; + address: string; + _id: string; + hack: HackathonProjectAttributes; + teamMembers: TeamMember[]; + eval: AIEvaluation[]; + progressUpdates: ProgressUpdate[]; }; // Team Member export type TeamMember = { - name: string; - email: string; - role: string; + name: string; + email: string; + role: string; }; export type CodeEntry = { - code: string; - comment: string; - language: string; + code: string; + comment: string; + language: string; }; export type ProgressUpdate = { - progress: string; - wins: string; - losses: string; - gamePlan: string; - actionItems: string[]; - code: CodeEntry[]; + progress: string; + wins: string; + losses: string; + gamePlan: string; + actionItems: string[]; + codeSnippets: CodeEntry[]; }; export type HackathonProjectAttributes = { - projectName: string; - problemStatement: string; - solutionDescription: string; - implementationDescription: string; - technologyStack: string[]; + projectName: string; + problemStatement: string; + solutionDescription: string; + implementationDescription: string; + technologyStack: string[]; }; export type AIEvaluation = { - coherenceScore: number; - feasibilityScore: number; - innovationScore: number; - funScore: number; - evaluationRemarks: string; -}; + coherenceScore: number; + feasabilityScore: number; + innovationScore: number; + funScore: number; + evaluationRemarks: string; + codeSnippets: CodeEntry[]; +}