diff --git a/package.json b/package.json
index 54bb671..fc4759f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "word-gpt-plus",
- "version": "0.3.4",
+ "version": "0.4.0",
"private": true,
"scripts": {
"dev": "vue-cli-service serve --port 3000",
@@ -29,7 +29,7 @@
},
"devDependencies": {
"@picgo/bump-version": "^1.1.2",
- "@types/office-js": "^1.0.376",
+ "@types/office-js": "^1.0.377",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
"@vue/cli-plugin-babel": "^5.0.8",
diff --git a/release/docker/manifest.xml b/release/docker/manifest.xml
deleted file mode 100644
index a2b3e30..0000000
--- a/release/docker/manifest.xml
+++ /dev/null
@@ -1,146 +0,0 @@
-
-
-
-
-
-
- 6b20e038-5f8e-4e3b-8481-976c5a9c0bc3
-
-
- 1.0.0.0
- Kuingsmile
- en-US
-
-
-
-
-
-
-
-
-
-
-
-
-
- AppDomain1
- AppDomain2
- AppDomain3
-
-
-
-
-
-
-
-
-
-
-
-
- ReadWriteDocument
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ButtonId1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/api/gemini.ts b/src/api/gemini.ts
index 3309b7b..e3187e6 100644
--- a/src/api/gemini.ts
+++ b/src/api/gemini.ts
@@ -24,7 +24,6 @@ async function createChatCompletionStream (options: ChatCompletionStreamOptions)
const model = genAI.getGenerativeModel({
model: options.geminiModel ?? 'gemini-pro'
})
- console.log('historyDialog', options.historyDialog.value)
const chat = model.startChat({
history: options.historyDialog.value,
generationConfig
@@ -32,8 +31,6 @@ async function createChatCompletionStream (options: ChatCompletionStreamOptions)
const result = await chat.sendMessage(options.messages)
const response = await result.response
const text = response.text()
- console.log('text', text)
- console.log('response', response)
updateResultAndHistory(text, options.messages, options.result, options.historyDialog)
} catch (error: any) {
handleError(error, options.result, options.errorIssue)
diff --git a/src/api/index.ts b/src/api/index.ts
index 4672330..07f90f3 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -4,6 +4,7 @@ import azure from './azure'
import palm from './palm'
import common from './common'
import gemini from './gemini'
+import ollama from './ollama'
export default {
webapi,
@@ -11,5 +12,6 @@ export default {
azure,
palm,
gemini,
- common
+ common,
+ ollama
}
diff --git a/src/api/ollama.ts b/src/api/ollama.ts
new file mode 100644
index 0000000..814bb8c
--- /dev/null
+++ b/src/api/ollama.ts
@@ -0,0 +1,50 @@
+import { Ref } from 'vue'
+import axios from 'axios'
+
+async function createChatCompletionStream (
+ ollamaEndpoint: string,
+ ollamaModel: string,
+ messages: any[],
+ result: Ref,
+ historyDialog: Ref,
+ errorIssue: Ref,
+ loading: Ref,
+ temperature?: number
+): Promise {
+ const formatedEndpoint = ollamaEndpoint.replace(/\/$/, '')
+ const url = `${formatedEndpoint}/api/chat`
+ const headers = {
+ 'Content-Type': 'application/json'
+ }
+ const body = {
+ model: ollamaModel,
+ options: {
+ temperature
+ },
+ stream: false,
+ messages
+ }
+ let response
+ try {
+ response = await axios.post(url, body, {
+ headers
+ })
+ if (response.status !== 200) {
+ throw new Error(`Status code: ${response.status}`)
+ }
+ result.value = response.data?.message?.content?.replace(/\\n/g, '\n') ?? ''
+ historyDialog.value.push({
+ role: 'assistant',
+ content: result.value
+ })
+ } catch (error) {
+ console.error(error)
+ result.value = String(error)
+ errorIssue.value = true
+ }
+ loading.value = false
+}
+
+export default {
+ createChatCompletionStream
+}
diff --git a/src/i18n/index.ts b/src/i18n/index.ts
index a07e121..5868bcf 100644
--- a/src/i18n/index.ts
+++ b/src/i18n/index.ts
@@ -28,6 +28,7 @@ const messages = {
settingModel: 'Model',
settingBasePath: 'Forward domain',
settingReplyLanguage: 'Reply',
+ settingOllamaEndpoint: 'endpoint',
settingProxy: 'Proxy',
settingClickToShow: 'Click to set',
settingEnableProxy: 'Enable proxy',
@@ -86,6 +87,7 @@ const messages = {
settingModel: '选择模型',
settingBasePath: '转发域名',
settingReplyLanguage: '回复语言',
+ settingOllamaEndpoint: 'endpoint',
settingProxy: '代理',
settingClickToShow: '点击设置',
settingEnableProxy: '启用代理',
diff --git a/src/pages/HomePage.vue b/src/pages/HomePage.vue
index 5e51586..3702224 100644
--- a/src/pages/HomePage.vue
+++ b/src/pages/HomePage.vue
@@ -210,7 +210,7 @@
{{ $t('start') }}
import { onBeforeMount, ref } from 'vue'
import { useRouter } from 'vue-router'
-import { localStorageKey, languageMap, buildInPrompt, availableModels, availableModelsForPalm, availableModelsForGemini } from '@/utils/constant'
+import { localStorageKey, languageMap, buildInPrompt, availableModels, availableModelsForPalm, availableModelsForGemini, availableModelsForOllama } from '@/utils/constant'
import { promptDbInstance } from '@/store/promtStore'
import { IStringKeyMap } from '@/types'
import { CirclePlus, Remove } from '@element-plus/icons-vue'
@@ -412,7 +412,7 @@ const replyLanguageList = Object.values(languageMap).map((key) => ({
value: key
}))
-const api = ref<'web-api' | 'official' | 'azure' | 'palm' | 'gemini'>('official')
+const api = ref<'web-api' | 'official' | 'azure' | 'palm' | 'gemini' | 'ollama'>('official')
const apiKey = ref('')
const accessToken = ref('')
const azureAPIKey = ref('')
@@ -443,6 +443,10 @@ const geminiMaxTokens = ref(800)
const geminiTemperature = ref(0.7)
const geminiModel = ref('gemini-pro')
+const ollamaEndpoint = ref('')
+const ollamaModel = ref('llama2')
+const ollamaTemperature = ref(0.7)
+
const systemPrompt = ref('')
const systemPromptSelected = ref('')
const systemPromptList = ref([])
@@ -554,7 +558,7 @@ function handelPromptChange (val: string) {
}
onBeforeMount(async () => {
- api.value = localStorage.getItem(localStorageKey.api) as 'web-api' | 'official' | 'azure' | 'palm' | 'gemini' || 'official'
+ api.value = localStorage.getItem(localStorageKey.api) as 'web-api' | 'official' | 'azure' | 'palm' | 'gemini' | 'ollama' || 'official'
replyLanguage.value = localStorage.getItem(localStorageKey.replyLanguage) || 'English'
localLanguage.value = localStorage.getItem(localStorageKey.localLanguage) || 'en'
apiKey.value = localStorage.getItem(localStorageKey.apiKey) || ''
@@ -599,6 +603,16 @@ onBeforeMount(async () => {
} else {
geminiModel.value = availableModelsForGemini['gemini-pro']
}
+ ollamaEndpoint.value = localStorage.getItem(localStorageKey.ollamaEndpoint) || ''
+ const ollamaModelTemp = localStorage.getItem(localStorageKey.ollamaModel) || availableModelsForOllama.llama2
+ if (Object.keys(availableModelsForOllama).includes(ollamaModelTemp)) {
+ ollamaModel.value = availableModelsForOllama[ollamaModelTemp]
+ } else if (Object.values(availableModelsForOllama).includes(ollamaModelTemp)) {
+ ollamaModel.value = ollamaModelTemp
+ } else {
+ ollamaModel.value = availableModelsForOllama.llama2
+ }
+ ollamaTemperature.value = forceNumber(localStorage.getItem(localStorageKey.ollamaTemperature)) || 0.7
insertType.value = localStorage.getItem(localStorageKey.insertType) || 'replace' as 'replace' | 'append' | 'newLine' | 'NoAction'
systemPrompt.value = localStorage.getItem(localStorageKey.defaultSystemPrompt) || 'Act like a personal assistant.'
await getSystemPromptList()
@@ -747,6 +761,23 @@ async function template (taskType: keyof typeof buildInPrompt | 'custom') {
geminiModel: geminiModel.value
}
)
+ } else if (api.value === 'ollama' && ollamaEndpoint.value) {
+ historyDialog.value = [
+ {
+ role: 'user',
+ content: systemMessage + '\n' + userMessage
+ }
+ ]
+ await API.ollama.createChatCompletionStream(
+ ollamaEndpoint.value,
+ ollamaModel.value,
+ historyDialog.value,
+ result,
+ historyDialog,
+ errorIssue,
+ loading,
+ ollamaTemperature.value
+ )
} else {
ElMessage.error('Set API Key or Access Token first')
return
@@ -891,6 +922,27 @@ async function continueChat () {
errorIssue.value = true
console.error(error)
}
+ } else if (api.value === 'ollama') {
+ try {
+ historyDialog.value.push({
+ role: 'user',
+ content: 'continue'
+ })
+ await API.ollama.createChatCompletionStream(
+ ollamaEndpoint.value,
+ ollamaModel.value,
+ historyDialog.value,
+ result,
+ historyDialog,
+ errorIssue,
+ loading,
+ ollamaTemperature.value
+ )
+ } catch (error) {
+ result.value = String(error)
+ errorIssue.value = true
+ console.error(error)
+ }
} else if (api.value === 'web-api') {
try {
const config = API.webapi.setUnofficalConfig(accessToken.value)
diff --git a/src/pages/SettingsPage.vue b/src/pages/SettingsPage.vue
index eeaa99e..7f021fb 100644
--- a/src/pages/SettingsPage.vue
+++ b/src/pages/SettingsPage.vue
@@ -89,6 +89,28 @@
@blur="handleAccessTokenChange"
/>
+
+
+
+ {{ $t('settingModel') }}
+
+
+
+
+
+
@@ -104,6 +126,76 @@
@blur="handleApiKeyChange"
/>
+
+
+
+ {{ $t('settingBasePath') }}
+
+
+
+
+
+
+
+ {{ $t('settingModel') }}
+
+
+
+
+
+
+
+
+
+ {{ $t('settingTemperature') }}
+
+
+
+
+
+
+
+ {{ $t('settingMaxTokens') }}
+
+
+
+
@@ -212,6 +304,28 @@
@blur="handlePalmAPIEndpointChange"
/>
+
+
+
+ {{ $t('settingModel') }}
+
+
+
+
+
+
@@ -316,66 +430,22 @@
-
-
- {{ $t('settingModel') }}
-
-
-
-
-
-
-
- {{ $t('settingBasePath') }}
+ {{ $t('settingOllamaEndpoint') }}
-
-
- {{ $t('settingModel') }}
-
-
-
-
-
-
-
@@ -383,13 +453,13 @@
@@ -405,28 +475,12 @@
-
-
-
-
- {{ $t('settingMaxTokens') }}
-
-
-
@@ -458,7 +512,7 @@