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

Chatgpt 3.5 turbo #1

Open
wants to merge 3 commits into
base: next-stablediffusion-gpt3.5
Choose a base branch
from
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
86 changes: 75 additions & 11 deletions app/(user)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,85 @@
'use client';
// import { MutableRefObject, useRef, useState } from 'react';
// import axios from 'axios';
import { ImageGenerator } from '../../components/ImageGenerator';
import { useState, useEffect } from 'react';
import ChatGPTAssistant from '../../components/ChatGPTAssistant';
import { ImageGeneratorForm } from '../../components/ImageGeneratorForm';

interface GeneratedImage {
imageUrl: string;
prompt: string;
}

export default function Home() {
const [imageUrl, setImageUrl] = useState('');
const [generatedImages, setGeneratedImages] = useState<GeneratedImage[]>([]);
const [isLoading, setIsLoading] = useState(false);

useEffect(() => {
const savedImages = JSON.parse(
localStorage.getItem('generatedImages') || '[]'
);
setGeneratedImages(savedImages);
}, []);

const handleGenerate = (generatedImageUrl: string, promptText: string) => {
setImageUrl(generatedImageUrl);
const newGeneratedImages = [
{ imageUrl: generatedImageUrl, prompt: promptText },
...generatedImages.slice(-9),
];
setGeneratedImages(newGeneratedImages);
localStorage.setItem('generatedImages', JSON.stringify(newGeneratedImages));
setIsLoading(false);
};

return (
<div className="h-screen bg-gray-900 text-gray-200 px-4">
<div className="h-screen text-gray-200 px-4">
<div className="container mx-auto">
<h1 className="text-4xl font-bold mb-8 mt-16">
Generate Image with Text
<h1 className="text-4xl font-bold mb-14 mt-8 text-center">
Generate Images with Text
</h1>
<ImageGenerator
onGenerate={function (imageUrl: string): void {
throw new Error('Function not implemented.');
}}
/>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="md:col-span-1">
<ImageGeneratorForm
onGenerate={handleGenerate}
isLoading={isLoading}
setIsLoading={setIsLoading}
/>
</div>
<div className="md:col-span-2">
{imageUrl && (
<div className="mt-0 text-center">
<h2 className="text-2xl font-bold mb-2">Generated Image:</h2>
<img
src={imageUrl}
alt="Generated"
className="border border-gray-300 inline-block"
/>
</div>
)}
</div>
</div>
<div className="mt-8 pb-12">
<h2 className="text-2xl font-bold mt-12 mb-8 text-center">
Last 10 Generated Images:
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{generatedImages.map((generatedImage, index) => (
<div
key={index}
className="bg-gray-700 p-4 rounded-lg shadow-md border border-gray-600"
>
<img
src={generatedImage.imageUrl}
alt="Generated"
className="border border-gray-300 w-full h-48 object-cover object-center"
/>
<p className="text-sm p-2 mb-2">{generatedImage.prompt}</p>
</div>
))}
</div>
</div>
</div>
<ChatGPTAssistant />
</div>
);
}
210 changes: 210 additions & 0 deletions components/ChatGPTAssistant.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
import { useState } from 'react';
import '@chatscope/chat-ui-kit-styles/dist/default/styles.min.css';
// import {
// MainContainer,
// ChatContainer,
// MessageList,
// Message,
// MessageInput,
// TypingIndicator,
// } from '@chatscope/chat-ui-kit-react';

import { ExpandCollapseToggle } from './ExpandCollapseToggle';

type MessageObject = {
message: string;
direction?: string;
sender: string;
sentTime?: string;
};

const systemMessage = {
role: 'system',
content:
"You are an AI trained to assist with prompt engineering and generating images using generative AI. Provide only the prompt text for generating images. Explain concepts like you're addressing a junior/mid-level web developer.",
};

const API_KEY = process.env.NEXT_PUBLIC_OPENAI_API_KEY;

function ChatGPTAssistant() {
const [typing, setTyping] = useState(false);
const [messages, setMessages] = useState<MessageObject[]>([
{
message:
"Hello, I'm ChatGPT! Let me know if you need help with your prompts!",
sentTime: 'just now',
sender: 'ChatGPT',
},
]);

const [inputValue, setInputValue] = useState('');
const [expanded, setExpanded] = useState(true);

const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (inputValue.trim() === '') return;
const formattedInputValue = `Give me a prompt for ${inputValue}`;
await handleSend(formattedInputValue);
setInputValue('');
};

// Add a function to toggle the expand/collapse state
const handleToggleExpand = () => {
setExpanded(!expanded);
};

const handleSend = async (message: string) => {
const newMessage = {
message,
direction: 'outgoing',
sender: 'user',
};

const newMessages = [...messages, newMessage];

setMessages(newMessages);

setTyping(true);

await processMessageToChatGPT(newMessages);
};

async function processMessageToChatGPT(chatMessages: MessageObject[]) {
// messages is an array of messages
// Format messages for chatGPT API
// API is expecting objects in format of { role: "user" or "assistant", "content": "message here"}
// So we need to reformat

let apiMessages = chatMessages.map((messageObject: MessageObject) => {
let role = '';
if (messageObject.sender === 'ChatGPT') {
role = 'assistant';
} else {
role = 'user';
}
return { role: role, content: messageObject.message };
});

// Get the request body set up with the model we plan to use
// and the messages which we formatted above. We add a system message in the front to'
// determine how we want chatGPT to act.
const apiRequestBody = {
model: 'gpt-3.5-turbo',
messages: [
systemMessage, // The system message DEFINES the logic of our chatGPT
...apiMessages, // The messages from our chat with ChatGPT
],
};

try {
const response = await fetch(
'https://api.openai.com/v1/chat/completions',
{
method: 'POST',
headers: {
Authorization: 'Bearer ' + API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(apiRequestBody),
}
);

if (!response.ok) {
throw new Error('Failed to fetch data from the ChatGPT API');
}

const data = await response.json();
console.log(data);
setMessages([
...chatMessages,
{
message: data.choices[0].message.content,
sender: 'ChatGPT',
},
]);
setTyping(false);
} catch (error) {
console.error(error);
setTyping(false);
}
}

function formatAssistantMessage(message: string) {
const parts = message.split(/("[^"]+")/);
return parts.map((part, index) => {
if (part.startsWith('"') && part.endsWith('"')) {
return (
<>
<br key={`before-${index}`} />
<p key={index} className="mb-0 mt-2 font-bold">
{part.slice(1, -1)}
</p>
<br key={`after-${index}`} />
</>
);
} else {
return <span key={index}>{part}</span>;
}
});
}

return (
<div
className={`fixed bottom-3 right-4 w-2/5 ${
expanded ? 'h-96' : 'h-16'
} bg-gray-800 p-4 rounded-lg shadow-lg`}
>
<div className="flex items-center justify-between">
<div className="text-xl font-semibold mb-4">
ChatGPT Prompt Assistant
</div>
<ExpandCollapseToggle
expanded={expanded}
onToggleExpand={handleToggleExpand}
/>
</div>

{expanded && (
<>
<div className="h-64 overflow-y-auto mb-4 p-1">
{messages.map((message, index) => (
<div
key={index}
className={`mb-2 ${
message.sender === 'user' ? 'text-right' : ''
}`}
>
<span
className={
message.sender === 'user'
? 'text-blue-400'
: 'text-green-400'
}
>
{message.sender === 'user' ? 'You: ' : 'Assistant: '}
</span>
{message.sender === 'ChatGPT'
? formatAssistantMessage(message.message)
: message.message}
</div>
))}
</div>

<form onSubmit={handleSubmit} className="flex">
<input
type="text"
className="flex-grow bg-gray-700 text-gray-200 rounded-l-lg p-2"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<button type="submit" className="bg-blue-500 p-2 rounded-r-lg">
Send
</button>
</form>
</>
)}
</div>
);
}

export default ChatGPTAssistant;
49 changes: 49 additions & 0 deletions components/ExpandCollapseToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';

interface ExpandCollapseToggleProps {
expanded: boolean;
onToggleExpand: () => void;
}

export const ExpandCollapseToggle: React.FC<ExpandCollapseToggleProps> = ({
expanded,
onToggleExpand,
}) => {
return (
<button
className="focus:outline-none"
onClick={onToggleExpand}
title={expanded ? 'Collapse' : 'Expand'}
>
{expanded ? (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-6 w-6 text-gray-300"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M19 9l-7 7-7-7"
/>
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-6 w-6 text-gray-300"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M5 15l7-7 7 7"
/>
</svg>
)}
</button>
);
};
Loading