Skip to content

Commit

Permalink
✨ Feature(custom): add ollama support
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuingsmile committed Mar 22, 2024
1 parent f976c51 commit aa0d61e
Show file tree
Hide file tree
Showing 11 changed files with 309 additions and 238 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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",
Expand Down
146 changes: 0 additions & 146 deletions release/docker/manifest.xml

This file was deleted.

3 changes: 0 additions & 3 deletions src/api/gemini.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,13 @@ 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
})
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)
Expand Down
4 changes: 3 additions & 1 deletion src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import azure from './azure'
import palm from './palm'
import common from './common'
import gemini from './gemini'
import ollama from './ollama'

export default {
webapi,
official,
azure,
palm,
gemini,
common
common,
ollama
}
50 changes: 50 additions & 0 deletions src/api/ollama.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Ref } from 'vue'
import axios from 'axios'

async function createChatCompletionStream (
ollamaEndpoint: string,
ollamaModel: string,
messages: any[],
result: Ref<string>,
historyDialog: Ref<any[]>,
errorIssue: Ref<boolean>,
loading: Ref<boolean>,
temperature?: number
): Promise<void> {
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
}
2 changes: 2 additions & 0 deletions src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const messages = {
settingModel: 'Model',
settingBasePath: 'Forward domain',
settingReplyLanguage: 'Reply',
settingOllamaEndpoint: 'endpoint',
settingProxy: 'Proxy',
settingClickToShow: 'Click to set',
settingEnableProxy: 'Enable proxy',
Expand Down Expand Up @@ -86,6 +87,7 @@ const messages = {
settingModel: '选择模型',
settingBasePath: '转发域名',
settingReplyLanguage: '回复语言',
settingOllamaEndpoint: 'endpoint',
settingProxy: '代理',
settingClickToShow: '点击设置',
settingEnableProxy: '启用代理',
Expand Down
60 changes: 56 additions & 4 deletions src/pages/HomePage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@
{{ $t('start') }}
</el-button>
<el-button
v-if="['web-api', 'azure', 'official', 'gemini'].includes(api)"
v-if="['web-api', 'azure', 'official', 'gemini', 'ollama'].includes(api)"
class="api-button"
type="success"
size="default"
Expand Down Expand Up @@ -398,7 +398,7 @@
<script lang="ts" setup>
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'
Expand All @@ -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('')
Expand Down Expand Up @@ -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<IStringKeyMap[]>([])
Expand Down Expand Up @@ -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) || ''
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit aa0d61e

Please sign in to comment.