Skip to content

Commit

Permalink
✨ Feature(custom): add support for chatGPT web API, using accessToken
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuingsmile committed Apr 25, 2023
1 parent 6010124 commit 8768f9e
Show file tree
Hide file tree
Showing 8 changed files with 424 additions and 55 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
"dependencies": {
"@element-plus/icons-vue": "^2.1.0",
"axios": "^1.3.6",
"chatgpt": "^5.2.2",
"core-js": "^3.30.1",
"dexie": "^3.2.3",
"element-plus": "^2.3.3",
"openai": "^3.2.1",
"unfetch": "^5.0.0",
"vue": "^3.2.47",
"vue-class-component": "^8.0.0-0",
"vue-i18n": "^9.2.2",
Expand Down
12 changes: 10 additions & 2 deletions src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { createI18n } from 'vue-i18n'
const messages = {
en: {
apiKey: 'API Key',
apiKeyDescription: 'Please enter your API key',
apiKeyDescription: 'API key',
accessToken: 'Access Token',
accessTokenDescription: 'Access Token',
chooseAPI: 'API',
chooseAPIDescription: 'Please choose API',
translate: 'Trans',
summarize: 'Sum',
polish: 'Polish',
Expand Down Expand Up @@ -53,7 +57,11 @@ const messages = {
},
'zh-cn': {
apiKey: 'API 密钥',
apiKeyDescription: '请输入您的 API 密钥',
apiKeyDescription: 'API 密钥',
accessToken: 'access token',
accessTokenDescription: 'access token',
chooseAPI: 'API',
chooseAPIDescription: '请选择API',
translate: '翻译',
summarize: '摘要',
polish: '润色',
Expand Down
165 changes: 131 additions & 34 deletions src/pages/HomePage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -391,16 +391,19 @@ import { Configuration, ConfigurationParameters, CreateChatCompletionRequest, Op
import { useRouter } from 'vue-router'
import { localStorageKey, languageMap, buildInPrompt } from '@/utils/constant'
import { promptDbInstance } from '@/store/promtStore'
import { IStringKeyMap } from '@/types'
import { IStringKeyMap, opts } from '@/types'
import { CirclePlus, Remove } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { ChatGPTUnofficialProxyAPI, ChatMessage } from 'chatgpt'
const replyLanguageList = Object.values(languageMap).map((key) => ({
label: key,
value: key
}))
const api = ref<'web-api' | 'official'>('web-api')
const apiKey = ref('')
const accessToken = ref('')
const localLanguage = ref('en')
const temperature = ref(0.7)
const maxTokens = ref(100)
Expand Down Expand Up @@ -431,6 +434,9 @@ const result = ref('res')
const loading = ref(false)
const router = useRouter()
const historyDialog = ref<any[]>([])
const parentMessageId = ref('')
const conversationId = ref('')
const insertType = ref('replace')
const insertTypeList = [
{
Expand Down Expand Up @@ -514,7 +520,9 @@ function handelPromptChange (val: string) {
}
onBeforeMount(async () => {
api.value = localStorage.getItem(localStorageKey.api) as 'web-api' | 'official' ?? 'web-api'
apiKey.value = localStorage.getItem(localStorageKey.apiKey) ?? ''
accessToken.value = localStorage.getItem(localStorageKey.accessToken) ?? ''
localLanguage.value = localStorage.getItem(localStorageKey.localLanguage) ?? 'en'
temperature.value = Number(localStorage.getItem(localStorageKey.temperature)) ?? 0.7
maxTokens.value = Number(localStorage.getItem(localStorageKey.maxTokens)) ?? 100
Expand Down Expand Up @@ -559,6 +567,14 @@ function setConfig (apiKey: string, basePath?: string): Configuration {
return config
}
function setUnofficalConfig (accessToken: string): opts {
const configParams: opts = {
accessToken,
apiReverseProxyUrl: 'https://ai.fakeopen.com/api/conversation'
}
return configParams
}
async function createChatCompletionStream (
config: Configuration,
messages: any[],
Expand Down Expand Up @@ -593,30 +609,66 @@ async function createChatCompletionStream (
}
} catch (error) {
result.value = 'error'
console.error(error)
}
loading.value = false
}
async function createChatCompletionUnoffical (
config: opts,
messages: any[]
) : Promise<void> {
const unOfficalAPI = new ChatGPTUnofficialProxyAPI(config)
let response
try {
response = await unOfficalAPI.sendMessage(
messages[0] + '\n' + messages[1],
{
timeoutMs: 30000,
onProgress: (partialResponse: ChatMessage) => {
result.value = partialResponse.text
}
}
)
parentMessageId.value = response.parentMessageId ?? ''
conversationId.value = response.conversationId ?? ''
} catch (error) {
result.value = 'error'
console.log(error)
}
loading.value = false
}
function insertResult () {
const paragraph = result.value.replace(/\n+/g, '\n').split('\n')
switch (insertType.value) {
case 'replace':
Word.run(async (context) => {
const range = context.document.getSelection()
range.insertText(result.value, 'Replace')
range.insertText(paragraph[0], 'Replace')
for (let i = paragraph.length - 1; i > 0; i--) {
range.insertParagraph(paragraph[i], 'After')
}
await context.sync()
})
break
case 'append':
Word.run(async (context) => {
const range = context.document.getSelection()
range.insertText(result.value, 'End')
range.insertText(paragraph[0], 'End')
for (let i = paragraph.length - 1; i > 0; i--) {
range.insertParagraph(paragraph[i], 'After')
}
await context.sync()
})
break
case 'newLine':
Word.run(async (context) => {
const range = context.document.getSelection()
range.insertParagraph(result.value, 'After')
range.insertParagraph(paragraph[0], 'After')
for (let i = paragraph.length - 1; i > 0; i--) {
range.insertParagraph(paragraph[i], 'After')
}
await context.sync()
})
break
Expand Down Expand Up @@ -645,31 +697,43 @@ async function template (taskType: keyof typeof buildInPrompt | 'custom') {
systemMessage = buildInPrompt[taskType].system(replyLanguage.value)
userMessage = buildInPrompt[taskType].user(selectedText, replyLanguage.value)
}
const config = setConfig(apiKey.value, basePath.value)
historyDialog.value = [
{
role: 'system',
content: systemMessage
},
{
role: 'user',
content: userMessage
}
]
await createChatCompletionStream(
config,
historyDialog.value,
maxTokens.value,
temperature.value,
model.value,
proxy.value
)
if (api.value === 'official' && apiKey.value !== '') {
const config = setConfig(apiKey.value, basePath.value)
historyDialog.value = [
{
role: 'system',
content: systemMessage
},
{
role: 'user',
content: userMessage
}
]
await createChatCompletionStream(
config,
historyDialog.value,
maxTokens.value,
temperature.value,
model.value,
proxy.value
)
} else if (api.value === 'web-api' && accessToken.value !== '') {
const config = setUnofficalConfig(accessToken.value)
await createChatCompletionUnoffical(config, [systemMessage, userMessage])
} else {
ElMessage.error('Set API Key or Access Token first')
return
}
if (result.value === 'error') {
ElMessage.error('Something went wrong')
return
}
insertResult()
}
function checkApiKey () {
if (apiKey.value === '') {
ElMessage.error('Go to settings to set API key')
if (apiKey.value === '' && accessToken.value === '') {
ElMessage.error('Set API Key or Access Token first')
return false
}
return true
Expand Down Expand Up @@ -711,15 +775,48 @@ async function continueChat () {
role: 'user',
content: 'continue'
})
await createChatCompletionStream(
setConfig(apiKey.value, basePath.value),
historyDialog.value,
maxTokens.value,
temperature.value,
model.value,
proxy.value
)
insertResult()
if (api.value === 'official') {
try {
await createChatCompletionStream(
setConfig(apiKey.value, basePath.value),
historyDialog.value,
maxTokens.value,
temperature.value,
model.value,
proxy.value
)
} catch (error) {
result.value = 'error'
console.log(error)
}
} else {
try {
const config = setUnofficalConfig(accessToken.value)
const unOfficalAPI = new ChatGPTUnofficialProxyAPI(config)
const response = await unOfficalAPI.sendMessage(
'continue',
{
timeoutMs: 30000,
parentMessageId: parentMessageId.value,
conversationId: conversationId.value,
onProgress: (partialResponse: ChatMessage) => {
result.value = partialResponse.text
}
}
)
parentMessageId.value = response.parentMessageId ?? ''
conversationId.value = response.conversationId ?? ''
} catch (error) {
result.value = 'error'
console.log(error)
}
}
loading.value = false
if (result.value === 'error') {
ElMessage.error('Error')
} else {
insertResult()
}
}
</script>
Expand Down
Loading

0 comments on commit 8768f9e

Please sign in to comment.