Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": [
"next/core-web-vitals",
"next/typescript"
]
}
11 changes: 11 additions & 0 deletions .gitmessage
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ✨ Style/Layout • UI tweaks, responsiveness, CSS, visual polish
# 🆕 New Feature • New page, function, section, or system
# 🔧 Fix/Tweak • Small fix, logic tweak, or config adjustment
# 🐛 Bug Fix • Solving a bug/issue in the code
# 🔥 Delete • Removing files, code, features, or dead content
# ♻️ Refactor • Rewriting without changing behavior
# 💥 Major Change • Breaking changes, rewrites, or restructured systems
# ✅ Add/Fix Tests • Writing or fixing tests
# 🚀 Deploy • Pushing to staging or production
# 📦 Dependencies • Installing/upgrading/removing libraries
# 📝 Content/Text • Updating copy, SEO text, or documentation
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"githubPullRequests.ignoredPullRequestBranches": [
"main"
]
}
15 changes: 15 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Start Next.js Application",
"type": "shell",
"command": "npm run dev",
"isBackground": true,
"problemMatcher": [
"$tsc"
],
"group": "build"
}
]
}
15 changes: 15 additions & 0 deletions COMMIT_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Commit Emoji Guide

| Emoji | Label | Use for… |
|-------|------------------|----------------------------------------------------------------|
| ✨ | Style/Layout | UI tweaks, responsiveness, CSS, visual polish |
| 🆕 | New Feature | New page, function, section, or system |
| 🔧 | Fix/Tweak | Small fix, logic tweak, or config adjustment |
| 🐛 | Bug Fix | Solving a bug/issue in the code |
| 🔥 | Delete | Removing files, code, features, or dead content |
| ♻️ | Refactor | Rewriting without changing behavior |
| 💥 | Major Change | Breaking changes, rewrites, or restructured systems |
| ✅ | Add/Fix Tests | Writing or fixing tests |
| 🚀 | Deploy | Pushing to staging or production |
| 📦 | Dependencies | Installing/upgrading/removing libraries |
| 📝 | Content/Text | Updating copy, SEO text, or documentation |
43 changes: 43 additions & 0 deletions analyze-commit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// A simple script to analyze the files in our recent commit
const { execSync } = require('child_process');

console.log('===== Git Commit Message Enhancement System Analysis =====\n');

// Get the last commit message
const lastCommitMessage = execSync('git log -1 --pretty=%B').toString().trim();
console.log('Last Commit Message:', lastCommitMessage);

// Count the number of files changed in the last commit
const filesChanged = execSync('git show --pretty="" --name-only HEAD').toString().trim().split('\n');
console.log(`\nTotal files changed: ${filesChanged.length}`);

// Count new files vs modified files
const newFiles = execSync('git diff-tree --no-commit-id --name-only --diff-filter=A -r HEAD').toString().trim().split('\n').filter(Boolean);
const modifiedFiles = execSync('git diff-tree --no-commit-id --name-only --diff-filter=M -r HEAD').toString().trim().split('\n').filter(Boolean);

console.log(`New files: ${newFiles.length}`);
console.log(`Modified files: ${modifiedFiles.length}`);

console.log('\n===== New Files =====');
newFiles.forEach(file => console.log(`- ${file}`));

console.log('\n===== Modified Files =====');
modifiedFiles.forEach(file => console.log(`- ${file}`));

console.log('\n===== Original commit message template =====');
try {
// Try to read the commit message template
const template = execSync('cat .gitmessage').toString().trim();
console.log(template);
} catch (error) {
console.log('Could not find .gitmessage template file');
}

console.log('\n===== Hook script that enhanced the message =====');
try {
// Display a snippet of the prepare-commit-msg hook
const hookScript = execSync('cat .git/hooks/prepare-commit-msg | grep -v "^#" | grep -v "^$"').toString().trim();
console.log(hookScript);
} catch (error) {
console.log('Could not find prepare-commit-msg hook script');
}
60 changes: 33 additions & 27 deletions app/api/assistants/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,41 @@ export const runtime = "nodejs";

// Create a new assistant
export async function POST() {
const assistant = await openai.beta.assistants.create({
instructions: "You are a helpful assistant.",
name: "Quickstart Assistant",
model: "gpt-4o",
tools: [
{ type: "code_interpreter" },
{
type: "function",
function: {
name: "get_weather",
description: "Determine weather in my location",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "The city and state e.g. San Francisco, CA",
},
unit: {
type: "string",
enum: ["c", "f"],
try {
const assistant = await openai.beta.assistants.create({
instructions: "You are a helpful assistant.",
name: "Quickstart Assistant",
model: "gpt-4o",
tools: [
{ type: "code_interpreter" },
{
type: "function",
function: {
name: "get_weather",
description: "Determine weather in my location",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "The city and state e.g. San Francisco, CA",
},
unit: {
type: "string",
enum: ["c", "f"],
},
},
required: ["location"],
},
required: ["location"],
},
},
},
{ type: "file_search" },
],
});
return Response.json({ assistantId: assistant.id });
{ type: "file_search" },
],
});
return Response.json({ assistantId: assistant.id });
} catch (error) {
console.error("Detailed error creating assistant:", error instanceof Error ? error.message : error);
console.error(error instanceof Error ? error.stack : "No stack trace available");
return new Response("Internal Server Error", { status: 500 });
}
}
31 changes: 21 additions & 10 deletions app/api/assistants/threads/[threadId]/messages/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,27 @@ export const runtime = "nodejs";

// Send a new message to a thread
export async function POST(request, { params: { threadId } }) {
const { content } = await request.json();
try {
const { content, attachments } = await request.json();

await openai.beta.threads.messages.create(threadId, {
role: "user",
content: content,
attachments: attachments,
});

await openai.beta.threads.messages.create(threadId, {
role: "user",
content: content,
});
const stream = openai.beta.threads.runs.stream(threadId, {
assistant_id: assistantId,
});

const stream = openai.beta.threads.runs.stream(threadId, {
assistant_id: assistantId,
});

return new Response(stream.toReadableStream());
return new Response(stream.toReadableStream());
} catch (error) {
console.error("Error processing message:", error);
return new Response(JSON.stringify({ error: "Error processing message" }), {
status: 500,
headers: {
"Content-Type": "application/json",
},
});
}
}
9 changes: 7 additions & 2 deletions app/api/assistants/threads/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ export const runtime = "nodejs";

// Create a new thread
export async function POST() {
const thread = await openai.beta.threads.create();
return Response.json({ threadId: thread.id });
try {
const thread = await openai.beta.threads.create();
return Response.json({ threadId: thread.id });
} catch (error) {
console.error("Error creating thread:", error);
return new Response("Error creating thread", { status: 500 });
}
}
36 changes: 26 additions & 10 deletions app/api/files/[fileId]/route.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
import { openai } from "@/app/openai";
import formidable, { File } from "formidable";
import fs from 'fs';

// download file by file ID
export async function GET(_request, { params: { fileId } }) {
const [file, fileContent] = await Promise.all([
openai.files.retrieve(fileId),
openai.files.content(fileId),
]);
return new Response(fileContent.body, {
headers: {
"Content-Disposition": `attachment; filename="${file.filename}"`,
},
// Handle file upload
export async function POST(request) {
const form = new formidable.IncomingForm();

const [fields, files] = await new Promise<[formidable.Fields, formidable.Files]>((resolve, reject) => {
form.parse(request, (err, fields, files) => {
if (err) reject(err);
resolve([fields, files]);
});
});

const uploadedFile = files.file[0] as File;

const fileStream = fs.createReadStream(uploadedFile.filepath);
const fileName = uploadedFile.originalFilename;

const openaiFile = await openai.files.create({
file: fileStream,
purpose: "assistants",
});

return new Response(JSON.stringify({ message: "File uploaded successfully", fileId: openaiFile.id, fileName }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}
67 changes: 67 additions & 0 deletions app/api/files/upload/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { openai } from "@/app/openai";
import { NextRequest } from 'next/server';
import { writeFile } from 'fs/promises';
import { join } from 'path';
import { randomUUID } from 'crypto';
import * as fs from 'fs';

export async function POST(request: NextRequest) {
try {
const formData = await request.formData();
const file = formData.get('file') as File;

if (!file) {
return new Response(JSON.stringify({ error: 'No file provided' }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
});
}

// Create a temporary file
const bytes = await file.arrayBuffer();
const buffer = Buffer.from(bytes);
const tempFilePath = join('/tmp', randomUUID());
await writeFile(tempFilePath, new Uint8Array(buffer));

// Get the file name
const fileName = file.name;

// Create a Blob from the file and convert it to a File object compatible with OpenAI
// This approach works better with TypeScript typing
const fileBlob = new Blob([buffer], { type: file.type });
const fileAsFile = new File([fileBlob], fileName, { type: file.type });

// Upload the file to OpenAI
const openaiFile = await openai.files.create({
file: fileAsFile,
purpose: "assistants",
});

// Clean up the temporary file
fs.unlink(tempFilePath, (err) => {
if (err) console.error('Error deleting temp file:', err);
});

return new Response(
JSON.stringify({
message: "File uploaded successfully",
fileId: openaiFile.id,
fileName
}),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
}
);

} catch (error) {
console.error('Error uploading file:', error);
return new Response(
JSON.stringify({ error: 'Error uploading file' }),
{
status: 500,
headers: { 'Content-Type': 'application/json' },
}
);
}
}
7 changes: 2 additions & 5 deletions app/assistant-config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
export let assistantId = ""; // set your assistant ID here

if (assistantId === "") {
assistantId = process.env.OPENAI_ASSISTANT_ID;
}
export const assistantId = "asst_xpO4Bk0VSlFEi4OfAks0T2J8"; // Using the created assistant ID directly
export const assistantToken = process.env.OPENAI_ASSISTANT_TOKEN;
Loading