Change the api key to local storage

This commit is contained in:
Rafi
2023-02-12 14:16:34 +08:00
parent edde4112c1
commit 6dfc92ede9
7 changed files with 119 additions and 19 deletions

View File

@@ -3,6 +3,7 @@ import { fetchEventSource } from '@microsoft/fetch-event-source'
const runtimeConfig = useRuntimeConfig()
const currentModel = useCurrentModel()
const openaiApiKey = useApiKey()
const fetchingResponse = ref(false)
const fetchReply = async (message, parentMessageId) => {
const ctrl = new AbortController()
@@ -15,6 +16,7 @@ const fetchReply = async (message, parentMessageId) => {
},
body: JSON.stringify({
model: currentModel.value,
openaiApiKey: openaiApiKey.value,
message: message,
parentMessageId: parentMessageId,
conversationId: currentConversation.value.id
@@ -126,8 +128,12 @@ onNuxtReady(() => {
<template v-slot:append>
<v-divider></v-divider>
<v-list>
<ApiKeyEditor/>
<ClientOnly>
<ApiKeyDialog/>
</ClientOnly>
<v-list-item
rounded="xl"
:prepend-icon="theme === 'light' ? 'dark_mode' : 'light_mode'"
:title="(theme === 'light' ? 'Dark' : 'Light') + ' mode'"
@click="toggleTheme"

View File

@@ -0,0 +1,84 @@
<template>
<v-dialog
v-model="dialog"
persistent
>
<template v-slot:activator="{ props }">
<v-list-item
rounded="xl"
v-bind="props"
prepend-icon="vpn_key"
color="primary"
>
Set OpenAI Api Key
</v-list-item>
</template>
<v-card>
<v-card-title>
<span class="text-h5">OpenAI Api Key</span>
</v-card-title>
<v-divider></v-divider>
<v-card-text>
<div>
Get a key:
<a target="_blank" href="https://platform.openai.com/account/api-keys">https://platform.openai.com/account/api-keys</a>
</div>
<div
class="mt-5 d-flex align-center"
>
<v-text-field
v-model="apiKey"
label="Api Key"
hide-details
clearable
:disabled="!editable"
></v-text-field>
<v-div
v-if="editable"
>
<v-btn class="ml-3" icon="done" @click="save"></v-btn>
</v-div>
<v-div
v-else
>
<v-btn class="ml-3" icon="edit" @click="editable = true"></v-btn>
</v-div>
</div>
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-alert
v-if="warningText"
density="compact"
type="warning"
:text="warningText"
></v-alert>
<v-spacer></v-spacer>
<v-btn
color="primary"
@click="dialog = false"
>
Close
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script setup>
const dialog = ref(false)
const apiKey = useApiKey()
const inputApiKey = ref('')
const editable = ref(false)
const warningText = ref(null)
const showWarning = (text) => {
warningText.value = text
setTimeout(() => {
warningText.value = null
}, 3000)
}
const save = async () => {
setApiKey(apiKey.value)
editable.value = false
}
</script>

View File

@@ -18,17 +18,17 @@
<v-card>
<v-card-title>
<span class="text-h5">OpenAI Models</span>
</v-card-title>
<v-divider></v-divider>
<v-card-text>
<div>
About the models:
<a target="_blank" href="https://platform.openai.com/docs/models/overview">https://platform.openai.com/docs/models/overview</a>
</div>
</v-card-title>
<v-divider></v-divider>
<v-card-text>
<div
v-for="(model, index) in models"
:key="index"
class="d-flex align-center"
class="mt-5 d-flex align-center"
>
<v-switch
v-model="currentModel"
@@ -109,7 +109,6 @@ const removeModel = (index) => {
models.value.splice(index, 1)
}
const save = async () => {
console.log(currentModel.value)
if (!currentModel.value) {
showWarning('Please select at least one model.')
return

View File

@@ -1,3 +1,5 @@
export const useModels = () => useState('models', () => getStoredModels())
export const useCurrentModel = () => useState('currentModel', () => getCurrentModel())
export const useApiKey = () => useState('apiKey', () => getStoredApiKey())

View File

@@ -1,6 +1,5 @@
import ChatGPTClient from '@waylaidwanderer/chatgpt-api'
import { PassThrough } from 'node:stream'
import {getSetting, setSetting} from "~/utils/keyv";
const serializeSSEEvent = (chunk) => {
let payload = "";
@@ -24,7 +23,6 @@ const serializeSSEEvent = (chunk) => {
}
export default defineEventHandler(async (event) => {
const runtimeConfig = useRuntimeConfig()
const body = await readBody(event)
const conversationId = body.conversationId ? body.conversationId.toString() : undefined
const parentMessageId = body.parentMessageId ? body.parentMessageId.toString() : undefined
@@ -38,9 +36,7 @@ export default defineEventHandler(async (event) => {
'Connection': 'keep-alive'
})
const apiKey = await getSetting('apiKey')
if (!apiKey) {
if (!body.openaiApiKey) {
writeToTunnel({
event: 'error',
data: JSON.stringify({
@@ -76,7 +72,7 @@ export default defineEventHandler(async (event) => {
uri: 'sqlite://database.sqlite'
};
const chatGptClient = new ChatGPTClient(apiKey, clientOptions, cacheOptions);
const chatGptClient = new ChatGPTClient(body.openaiApiKey, clientOptions, cacheOptions);
try {
const response = await chatGptClient.sendMessage(body.message, {

View File

@@ -2,4 +2,5 @@
export const STORAGE_KEY = {
OPENAI_MODELS: 'openai_models',
CURRENT_OPENAI_MODEL: 'current_openai_model',
OPENAI_API_KEY: 'openai_api_key',
}

View File

@@ -1,11 +1,13 @@
import {useCurrentModel, useModels} from "~/composables/states";
const get = (key) => {
if (typeof window !== 'undefined') {
let val = localStorage.getItem(key)
if (val) {
val = JSON.parse(val)
}
return val
}
return null
}
const set = (key, val) => {
@@ -41,3 +43,13 @@ export const getCurrentModel = () => {
}
return model
}
export const setApiKey = (val) => {
const apiKey = useApiKey()
set(STORAGE_KEY.OPENAI_API_KEY, val)
apiKey.value = val
}
export const getStoredApiKey = () => {
return get(STORAGE_KEY.OPENAI_API_KEY)
}