Skip to content

Commit

Permalink
update setting, history content
Browse files Browse the repository at this point in the history
  • Loading branch information
SchneeHertz committed Nov 21, 2023
1 parent 8eb084f commit a8d7cba
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 96 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ v2.1支持0613系列的GPT-4, GPT-3.5

![setting.jpg](https://raw.githubusercontent.com/SchneeHertz/chat-xiuliu/master/screenshots/setting.jpg)

![setting2.jpg](https://raw.githubusercontent.com/SchneeHertz/chat-xiuliu/master/screenshots/setting2.jpg)


## 可选语音识别功能
- _下载[whisper-standalone-win](https://github.com/Purfview/whisper-standalone-win)r145.3(最好有张N卡,不然运行时很慢,可选,语音功能)_
Expand Down
4 changes: 4 additions & 0 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ declare module 'vue' {
NAvatar: typeof import('naive-ui')['NAvatar']
NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard']
NCheckbox: typeof import('naive-ui')['NCheckbox']
NCheckboxGroup: typeof import('naive-ui')['NCheckboxGroup']
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
Expand All @@ -31,6 +33,8 @@ declare module 'vue' {
NSpace: typeof import('naive-ui')['NSpace']
NSpin: typeof import('naive-ui')['NSpin']
NSwitch: typeof import('naive-ui')['NSwitch']
NTabPane: typeof import('naive-ui')['NTabPane']
NTabs: typeof import('naive-ui')['NTabs']
NThing: typeof import('naive-ui')['NThing']
NUpload: typeof import('naive-ui')['NUpload']
Setting: typeof import('./src/components/Setting.vue')['default']
Expand Down
28 changes: 20 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ const {
systemPrompt,
useProxy,
proxyObject,
functionCallingRoundLimit = 3
historyRoundLimit = 12,
functionCallingRoundLimit = 3,
disableFunctions = [],
searchResultLimit = 5,
webPageContentTokenLengthLimit = 6000,
} = config
const proxyString = `${proxyObject.protocol}://${proxyObject.host}:${proxyObject.port}`

Expand Down Expand Up @@ -289,6 +293,10 @@ const addHistory = (lines) => {
}

const useOpenaiChatStreamFunction = useAzureOpenai ? azureOpenaiChatStream : openaiChatStream
const addtionalFunctionLimit = {
searchResultLimit,
webPageContentTokenLengthLimit
}
const resolveMessages = async ({ resToolCalls, resText, resTextTemp, messages, from, useFunctionCalling = false }) => {

console.log(`use ${useAzureOpenai ? AZURE_CHAT_MODEL : DEFAULT_MODEL}`)
Expand All @@ -306,7 +314,7 @@ const resolveMessages = async ({ resToolCalls, resText, resTextTemp, messages, f
content: 'use Function Calling'
})
messages.push({ role: 'assistant', content: null, tool_calls: resToolCalls })
addHistory([{ role: 'assistant', content: null, tool_calls: resToolCalls }])
// addHistory([{ role: 'assistant', content: null, tool_calls: resToolCalls }])
for (let toolCall of resToolCalls) {
let functionCallResult
try {
Expand All @@ -317,18 +325,18 @@ const resolveMessages = async ({ resToolCalls, resText, resTextTemp, messages, f
})
switch (toolCall.function.name) {
case 'getHistoricalConversationContent':
functionCallResult = await functionList[toolCall.function.name](_.assign({ dbTable: memoryTable }, JSON.parse(toolCall.function.arguments)))
functionCallResult = await functionList[toolCall.function.name](_.assign({ dbTable: memoryTable }, JSON.parse(toolCall.function.arguments)), addtionalFunctionLimit)
break
default:
functionCallResult = await functionList[toolCall.function.name](JSON.parse(toolCall.function.arguments))
functionCallResult = await functionList[toolCall.function.name](JSON.parse(toolCall.function.arguments), addtionalFunctionLimit)
break
}
} catch (e) {
console.log(e)
functionCallResult = e.message
}
messages.push({ role: 'tool', tool_call_id: toolCall.id, content: functionCallResult + '' })
addHistory([{ role: 'tool', tool_call_id: toolCall.id, content: functionCallResult + '' }])
// addHistory([{ role: 'tool', tool_call_id: toolCall.id, content: functionCallResult + '' }])
console.log({ role: 'tool', tool_call_id: toolCall.id, content: functionCallResult + '' })
messageLogAndSend({
id: nanoid(),
Expand All @@ -342,8 +350,8 @@ const resolveMessages = async ({ resToolCalls, resText, resTextTemp, messages, f
let prepareChatOption = { messages }

if (useFunctionCalling) {
prepareChatOption.tools = functionInfo
prepareChatOption.tool_choice = 'auto'
prepareChatOption.tools = functionInfo.filter(f => !disableFunctions.includes(f?.function?.name))
if (!_.isEmpty(prepareChatOption.tools)) prepareChatOption.tool_choice = 'auto'
}

// alert chat
Expand Down Expand Up @@ -442,7 +450,7 @@ const resloveAdminPrompt = async ({ prompt, promptType = 'string', triggerRecord
{ role: 'system', content: givenSystemPrompt ? givenSystemPrompt : systemPrompt },
{ role: 'user', content: `我的名字是${ADMIN_NAME}` },
{ role: 'assistant', content: `你好, ${ADMIN_NAME}` },
..._.takeRight(history, 12),
..._.takeRight(history, historyRoundLimit),
{ role: 'user', content: prompt }
]
addHistory([{ role: 'user', content: prompt }])
Expand Down Expand Up @@ -623,3 +631,7 @@ ipcMain.handle('load-setting', async () => {
ipcMain.handle('save-setting', async (event, receiveSetting) => {
return await fs.promises.writeFile(path.join(STORE_PATH, 'config.json'), JSON.stringify(receiveSetting, null, ' '), { encoding: 'utf-8' })
})

ipcMain.handle('get-function-info', async () => {
return functionInfo
})
8 changes: 4 additions & 4 deletions modules/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ const functionAction = {
}
}

const getInformationFromGoogle = async ({ queryString }) => {
const getInformationFromGoogle = async ({ queryString }, { searchResultLimit }) => {
let options = { proxy: useProxy ? proxyString : undefined }
let additionalQueryParam = {
// lr: 'lang_zh-CN',
Expand All @@ -209,11 +209,11 @@ const getInformationFromGoogle = async ({ queryString }) => {
// gl: 'cn',
safe: 'high'
}
let googleRes = await google({ options, disableConsole: true, query: queryString, limit: 5, additionalQueryParam })
let googleRes = await google({ options, disableConsole: true, query: queryString, limit: searchResultLimit, additionalQueryParam })
return googleRes.map(l=>`[${l.title}](${l.link}): ${l.snippet}`).join('\n##\n')
}

const getContentOfWebpage = async ({ url }) => {
const getContentOfWebpage = async ({ url }, { webPageContentTokenLengthLimit }) => {
return await axios.get(url, { proxy: useProxy ? proxyObject : undefined })
.then(async res=>{
let html = await res.data
Expand All @@ -225,7 +225,7 @@ const getContentOfWebpage = async ({ url }) => {
{ selector: 'img', format: 'skip' },
]
})
return sliceStringbyTokenLength(content, 6000)
return sliceStringbyTokenLength(content, webPageContentTokenLengthLimit)
})
}

Expand Down
Binary file modified screenshots/setting.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/setting2.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
198 changes: 118 additions & 80 deletions src/components/Setting.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup>
import { ref } from 'vue'
import { ref, onMounted, computed } from 'vue'
import { MdSettings, MdFolderOpen } from '@vicons/ionicons4'
import Dialog from './Dialog.vue'
Expand Down Expand Up @@ -69,6 +69,20 @@ const alertSwitchVisionModel = () => {
})
}
const functionList = ref([])
let selectFunctions = computed({
get: () => {
return _.difference(functionList.value, config.value.disableFunctions)
},
set: (val) => {
config.value.disableFunctions = _.difference(functionList.value, val)
}
})
onMounted(async () => {
let functionInfo = await ipcRenderer.invoke('get-function-info')
functionList.value = functionInfo.map(f => f?.function?.name)
})
defineExpose({
openConfig
})
Expand All @@ -84,85 +98,109 @@ defineExpose({
</n-button>
<n-modal v-model:show="showSettingModal" preset="dialog" title="设置" positive-text="保存后重启应用" negative-text="取消"
@positive-click="saveSettingAndRestart" @negative-click="cancelSetting" :show-icon="false" :style="{ width: '51em' }">
<n-form ref="formRef" :model="config" label-placement="left" label-width="auto" require-mark-placement="right-hanging"
size="small">
<n-form-item label="使用Azure OpenAI" path="useAzureOpenai">
<n-switch v-model:value="config.useAzureOpenai" />
</n-form-item>
<n-form-item label="OPENAI_API_KEY" path="OPENAI_API_KEY" v-show="!config.useAzureOpenai">
<n-input v-model:value="config.OPENAI_API_KEY" placeholder="sk-48chars" type="password"
show-password-on="click" />
</n-form-item>
<n-form-item label="OPENAI_API_ENDPOINT" path="OPENAI_API_ENDPOINT" v-show="!config.useAzureOpenai">
<n-input v-model:value="config.OPENAI_API_ENDPOINT" placeholder="like https://api.openai.com/v1" />
</n-form-item>
<n-form-item label="DEFAULT_MODEL" path="DEFAULT_MODEL" v-show="!config.useAzureOpenai">
<n-select v-model:value="config.DEFAULT_MODEL" :options="model_options" @change="alertSwitchVisionModel"/>
</n-form-item>
<n-form-item label="AZURE_OPENAI_KEY" path="AZURE_OPENAI_KEY" v-show="config.useAzureOpenai">
<n-input v-model:value="config.AZURE_OPENAI_KEY" placeholder="32chars" type="password" show-password-on="click" />
</n-form-item>
<n-form-item label="AZURE_OPENAI_ENDPOINT" path="AZURE_OPENAI_ENDPOINT" v-show="config.useAzureOpenai">
<n-input v-model:value="config.AZURE_OPENAI_ENDPOINT" placeholder="endpoint-name" />
</n-form-item>
<n-form-item label="AZURE_API_VERSION" path="AZURE_API_VERSION" v-show="config.useAzureOpenai">
<n-input v-model:value="config.AZURE_API_VERSION" placeholder="like 2023-07-01-preview" />
</n-form-item>
<n-form-item label="AZURE_CHAT_MODEL" path="AZURE_CHAT_MODEL" v-show="config.useAzureOpenai">
<n-input v-model:value="config.AZURE_CHAT_MODEL" placeholder="like gpt-35-turbo-16k" />
</n-form-item>
<n-form-item label="AZURE_EMBEDDING_MODEL" path="AZURE_EMBEDDING_MODEL" v-show="config.useAzureOpenai">
<n-input v-model:value="config.AZURE_EMBEDDING_MODEL" placeholder="like text-embedding-ada-002" />
</n-form-item>
<n-form-item label="SpeechSynthesisVoiceName" path="SpeechSynthesisVoiceName">
<n-input v-model:value="config.SpeechSynthesisVoiceName" placeholder="like zh-CN-XiaoyiNeural" />
</n-form-item>
<n-form-item label="你的称呼" path="ADMIN_NAME">
<n-input v-model:value="config.ADMIN_NAME" />
</n-form-item>
<n-form-item label="AI的名字" path="AI_NAME">
<n-input v-model:value="config.AI_NAME" />
</n-form-item>
<n-form-item label="设定" path="systemPrompt">
<n-input v-model:value="config.systemPrompt" placeholder="AI的设定,chatgpt的默认值是'You are a helpful assistant.'"
type="textarea" :autosize="{
minRows: 2,
maxRows: 4
}" />
</n-form-item>
<n-form-item label="可写文件夹" path="writeFolder">
<n-input-group>
<n-input v-model:value="config.writeFolder" placeholder="允许AI写入文件的文件夹" />
<n-button type="default" @click="chooseWriteFolder">
<n-icon>
<MdFolderOpen />
</n-icon>
</n-button>
</n-input-group>
</n-form-item>
<n-form-item label="使用高级解释器" path="allowPowerfulInterpreter">
<n-switch v-model:value="config.allowPowerfulInterpreter" @update:value="alertJSPRisk" />
</n-form-item>
<n-form-item label="函数调用轮次限制" path="functionCallingRoundLimit">
<n-input-number v-model:value="config.functionCallingRoundLimit" :precision="0" :min="0" :parse="parseNumber"/>
</n-form-item>
<n-form-item label="使用代理服务器" path="useProxy">
<n-switch v-model:value="config.useProxy" />
</n-form-item>
<n-form-item label="代理服务器" :show-feedback="false" v-show="config.useProxy">
<n-grid :cols="24" :x-gap="8">
<n-form-item-gi path="proxyObject.protocol" :span="4">
<n-input v-model:value="config.proxyObject.protocol" title="protocol, like http"/>
</n-form-item-gi>
<n-form-item-gi path="proxyObject.host" :span="8">
<n-input v-model:value="config.proxyObject.host" title="host, like 127.0.0.1" />
</n-form-item-gi>
<n-form-item-gi path="proxyObject.port" :span="4">
<n-input-number v-model:value="config.proxyObject.port" title="port, like 7890" :show-button="false" />
</n-form-item-gi>
</n-grid>
</n-form-item>
</n-form>
<n-tabs type="line" animated default-value="general">
<n-tab-pane name="general" tab="常用">
<n-form ref="formRef" :model="config" label-placement="left" label-width="210px" size="small">
<n-form-item label="使用Azure OpenAI" path="useAzureOpenai">
<n-switch v-model:value="config.useAzureOpenai" />
</n-form-item>
<n-form-item label="OPENAI_API_KEY" path="OPENAI_API_KEY" v-show="!config.useAzureOpenai">
<n-input v-model:value="config.OPENAI_API_KEY" placeholder="sk-48chars" type="password"
show-password-on="click" />
</n-form-item>
<n-form-item label="OPENAI_API_ENDPOINT" path="OPENAI_API_ENDPOINT" v-show="!config.useAzureOpenai">
<n-input v-model:value="config.OPENAI_API_ENDPOINT" placeholder="like https://api.openai.com/v1" />
</n-form-item>
<n-form-item label="DEFAULT_MODEL" path="DEFAULT_MODEL" v-show="!config.useAzureOpenai">
<n-select v-model:value="config.DEFAULT_MODEL" :options="model_options" @change="alertSwitchVisionModel"/>
</n-form-item>
<n-form-item label="AZURE_OPENAI_KEY" path="AZURE_OPENAI_KEY" v-show="config.useAzureOpenai">
<n-input v-model:value="config.AZURE_OPENAI_KEY" placeholder="32chars" type="password" show-password-on="click" />
</n-form-item>
<n-form-item label="AZURE_OPENAI_ENDPOINT" path="AZURE_OPENAI_ENDPOINT" v-show="config.useAzureOpenai">
<n-input v-model:value="config.AZURE_OPENAI_ENDPOINT" placeholder="endpoint-name" />
</n-form-item>
<n-form-item label="AZURE_API_VERSION" path="AZURE_API_VERSION" v-show="config.useAzureOpenai">
<n-input v-model:value="config.AZURE_API_VERSION" placeholder="like 2023-07-01-preview" />
</n-form-item>
<n-form-item label="AZURE_CHAT_MODEL" path="AZURE_CHAT_MODEL" v-show="config.useAzureOpenai">
<n-input v-model:value="config.AZURE_CHAT_MODEL" placeholder="like gpt-35-turbo-16k" />
</n-form-item>
<n-form-item label="AZURE_EMBEDDING_MODEL" path="AZURE_EMBEDDING_MODEL" v-show="config.useAzureOpenai">
<n-input v-model:value="config.AZURE_EMBEDDING_MODEL" placeholder="like text-embedding-ada-002" />
</n-form-item>
<n-form-item label="你的称呼" path="ADMIN_NAME">
<n-input v-model:value="config.ADMIN_NAME" />
</n-form-item>
<n-form-item label="AI的名字" path="AI_NAME">
<n-input v-model:value="config.AI_NAME" />
</n-form-item>
<n-form-item label="设定" path="systemPrompt">
<n-input v-model:value="config.systemPrompt" placeholder="AI的设定,chatgpt的默认值是'You are a helpful assistant.'"
type="textarea" :autosize="{
minRows: 2,
maxRows: 4
}" />
</n-form-item>
<n-form-item label="使用代理服务器" path="useProxy">
<n-switch v-model:value="config.useProxy" />
</n-form-item>
<n-form-item label="代理服务器" :show-feedback="false" v-show="config.useProxy">
<n-grid :cols="24" :x-gap="8">
<n-form-item-gi path="proxyObject.protocol" :span="4">
<n-input v-model:value="config.proxyObject.protocol" title="protocol, like http"/>
</n-form-item-gi>
<n-form-item-gi path="proxyObject.host" :span="8">
<n-input v-model:value="config.proxyObject.host" title="host, like 127.0.0.1" />
</n-form-item-gi>
<n-form-item-gi path="proxyObject.port" :span="4">
<n-input-number v-model:value="config.proxyObject.port" title="port, like 7890" :show-button="false" />
</n-form-item-gi>
</n-grid>
</n-form-item>
</n-form>
</n-tab-pane>
<n-tab-pane name="advance" tab="高级">
<n-form ref="formRef" :model="config" label-placement="left" label-width="auto" require-mark-placement="right-hanging"
size="small">
<n-form-item label="SpeechSynthesisVoiceName" path="SpeechSynthesisVoiceName">
<n-input v-model:value="config.SpeechSynthesisVoiceName" placeholder="like zh-CN-XiaoyiNeural" />
</n-form-item>
<n-form-item label="上下文对话条数" path="historyRoundLimit">
<n-input-number v-model:value="config.historyRoundLimit" :default-value="12" :precision="0" :min="0" :parse="parseNumber"/>
</n-form-item>
<n-form-item label="函数调用轮次限制" path="functionCallingRoundLimit">
<n-input-number v-model:value="config.functionCallingRoundLimit" :precision="0" :min="0" :parse="parseNumber"/>
</n-form-item>
<n-form-item label="激活的函数调用函数">
<n-checkbox-group v-model:value="selectFunctions">
<n-space>
<n-checkbox v-for="func in functionList" :key="func" :value="func" :label="func" />
</n-space>
</n-checkbox-group>
</n-form-item>
<n-form-item label="使用nodejs解释器" path="allowPowerfulInterpreter">
<n-switch v-model:value="config.allowPowerfulInterpreter" @update:value="alertJSPRisk" />
</n-form-item>
<n-form-item label="搜索结果个数" path="searchResultLimit">
<n-input-number v-model:value="config.searchResultLimit" :default-value="5" :precision="0" :min="0" :parse="parseNumber"/>
</n-form-item>
<n-form-item label="网页内容长度限制" path="webPageContentTokenLengthLimit">
<n-input-number v-model:value="config.webPageContentTokenLengthLimit" :default-value="6000" :precision="0" :min="0" :parse="parseNumber"/>
</n-form-item>
<n-form-item label="可写文件夹" path="writeFolder">
<n-input-group>
<n-input v-model:value="config.writeFolder" placeholder="允许AI写入文件的文件夹" />
<n-button type="default" @click="chooseWriteFolder">
<n-icon>
<MdFolderOpen />
</n-icon>
</n-button>
</n-input-group>
</n-form-item>
</n-form>
</n-tab-pane>
</n-tabs>
</n-modal>
<n-dialog-provider>
<Dialog ref="dialogRef" />
Expand Down
12 changes: 8 additions & 4 deletions utils/loadConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,23 @@ try {
AZURE_API_VERSION: '',
AZURE_CHAT_MODEL: '',
AZURE_EMBEDDING_MODEL: '',
SpeechSynthesisVoiceName: 'zh-CN-XiaoyiNeural',
ADMIN_NAME: 'Chell',
AI_NAME: '休留',
systemPrompt: '你是虚拟猫娘休留,以下是你在回复时应该遵循的规则:\n1.你能够灵活的运用猫娘的风格进行回复.\n2.调用函数来提高你的回复质量',
writeFolder: '',
allowPowerfulInterpreter: false,
useProxy: false,
proxyObject: {
protocol: 'http',
host: '127.0.0.1',
port: 7890
},
functionCallingRoundLimit: 3
SpeechSynthesisVoiceName: 'zh-CN-XiaoyiNeural',
historyRoundLimit: 12,
functionCallingRoundLimit: 3,
disableFunctions: [],
allowPowerfulInterpreter: false,
searchResultLimit: 5,
webPageContentTokenLengthLimit: 6000,
writeFolder: '',
}
fs.writeFileSync(path.join(STORE_PATH, 'config.json'), JSON.stringify(config, null, ' '), { encoding: 'utf-8' })
}
Expand Down

0 comments on commit a8d7cba

Please sign in to comment.