diff --git a/app/components/RiskyButCoolAPIKeyInput.tsx b/app/components/RiskyButCoolAPIKeyInput.tsx
index cf0362e..5151a9a 100644
--- a/app/components/RiskyButCoolAPIKeyInput.tsx
+++ b/app/components/RiskyButCoolAPIKeyInput.tsx
@@ -1,13 +1,10 @@
-import { Icon, useBreakpoint } from '@tldraw/tldraw'
import { ChangeEvent, useCallback } from 'react'
+import { QuestionIcon } from '@100mslive/react-icons'
export function RiskyButCoolAPIKeyInput() {
- const breakpoint = useBreakpoint()
-
- // Store the API key locally, but ONLY in development mode
const handleChange = useCallback((e: ChangeEvent) => {
- if (process.env.NODE_ENV === 'development') {
- localStorage.setItem('makeitreal_key', e.target.value)
+ if (typeof window !== 'undefined') {
+ sessionStorage.setItem('OPEN_AI_KEY', e.target.value)
}
}, [])
@@ -18,19 +15,14 @@ export function RiskyButCoolAPIKeyInput() {
}, [])
return (
-
-
-
-
-
+
+
+ Your OpenAI API Key
+
)
}
diff --git a/app/globals.css b/app/globals.css
index a0ccbb9..bed2b01 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -167,7 +167,7 @@ h4 {
}
.input__wrapper:not(:focus-within)::after {
- content: 'Your OpenAI API Key (risky but cool)';
+ content: 'Enter your OpenAI API Key (risky but cool)';
display: block;
position: absolute;
inset: 0px;
@@ -322,10 +322,11 @@ input::placeholder {
}
.input-label {
+ display: flex;
font-size: 14px;
font-weight: 500;
margin-bottom: 5px;
- align-items: start;
+ align-items: center;
}
.tabs-container {
diff --git a/app/lib/fetchFromOpenAi.tsx b/app/lib/fetchFromOpenAi.tsx
index 0e18a2e..4967ea6 100644
--- a/app/lib/fetchFromOpenAi.tsx
+++ b/app/lib/fetchFromOpenAi.tsx
@@ -1,9 +1,11 @@
'use server'
+import { toast } from 'react-toastify'
+
export async function fetchFromOpenAi(
providedApiKey: string,
body: GPT4VCompletionRequest
-): Promise {
+): Promise {
const apiKey = providedApiKey ?? process.env.OPENAI_API_KEY
if (!apiKey) {
@@ -11,9 +13,8 @@ export async function fetchFromOpenAi(
'You need to provide an API key. Make sure OPENAI_API_KEY is set in your .env file.'
)
}
-
try {
- const repsonse = await fetch('https://api.openai.com/v1/chat/completions', {
+ const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -21,11 +22,15 @@ export async function fetchFromOpenAi(
},
body: JSON.stringify(body),
})
+ const jsonData = await response.json()
- return await repsonse.json()
+ if (jsonData.error) {
+ throw jsonData.error
+ }
+ return jsonData
} catch (e) {
console.error(e)
- throw new Error('Sorry, there was an error fetching from OpenAI')
+ return e.message
}
}
diff --git a/app/makeReal.tsx b/app/makeReal.tsx
index 9d0f373..ccf3de3 100644
--- a/app/makeReal.tsx
+++ b/app/makeReal.tsx
@@ -7,6 +7,7 @@ import {
MessageContent,
fetchFromOpenAi,
} from './lib/fetchFromOpenAi'
+import { toast } from 'react-toastify'
const SYSTEM_PROMPT = `You are an expert at constructing interative polls and quizzes for audiences.
Your job is to accept a design and turn it into a poll with multiple options for attendees to vote on to make a session more interative.
@@ -38,13 +39,11 @@ export async function makeReal(
// If you're using the API key input, we preference the key from there.
// It's okay if this is undefined—it will just mean that we'll use the
// one in the .env file instead.
- const apiKeyFromDangerousApiKeyInput = (
- document.body.querySelector('#openai_key_risky_but_cool') as HTMLInputElement
- )?.value
+ const apiKeyFromDangerousApiKeyInput = sessionStorage.getItem('OPEN_AI_KEY')
// make a request to openai. `fetchFromOpenAi` is a next.js server action,
// so our api key is hidden.
- const openAiResponse: GPT4VCompletionResponse = await fetchFromOpenAi(
+ const openAiResponse: GPT4VCompletionResponse | string = await fetchFromOpenAi(
apiKeyFromDangerousApiKeyInput,
{
model: 'gpt-4-vision-preview',
@@ -53,6 +52,9 @@ export async function makeReal(
messages: prompt,
}
)
+ if (typeof openAiResponse === 'string') {
+ throw openAiResponse
+ }
if ('choices' in openAiResponse) {
const messageContent = openAiResponse.choices[0].message.content
@@ -62,7 +64,7 @@ export async function makeReal(
} catch (e) {
// if something went wrong, get rid of the unnecessary response shape
// editor.deleteShape(responseShapeId)
- throw e
+ toast.error(e)
}
}