This commit is contained in:
josc146
2024-08-05 19:01:06 +08:00
parent c496f87fe6
commit 6877a1b7bc
22 changed files with 134 additions and 184 deletions
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "Immer das schwebende Fenster anzeigen, die Seitenleiste für alle Website-Adapter deaktivieren", "Always display floating window, disable sidebar for all site adapters": "Immer das schwebende Fenster anzeigen, die Seitenleiste für alle Website-Adapter deaktivieren",
"Allow ESC to close all floating windows": "ESC-Taste zum Schließen aller schwebenden Fenster zulassen", "Allow ESC to close all floating windows": "ESC-Taste zum Schließen aller schwebenden Fenster zulassen",
"Export All Data": "Alle Daten exportieren", "Export All Data": "Alle Daten exportieren",
"Import All Data": "Alle Daten importieren" "Import All Data": "Alle Daten importieren",
"Keep-Alive Time": "Keep-Alive-Zeit",
"5m": "5m",
"30m": "30m",
"Forever": "Für immer"
} }
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "Always display floating window, disable sidebar for all site adapters", "Always display floating window, disable sidebar for all site adapters": "Always display floating window, disable sidebar for all site adapters",
"Allow ESC to close all floating windows": "Allow ESC to close all floating windows", "Allow ESC to close all floating windows": "Allow ESC to close all floating windows",
"Export All Data": "Export All Data", "Export All Data": "Export All Data",
"Import All Data": "Import All Data" "Import All Data": "Import All Data",
"Keep-Alive Time": "Keep-Alive Time",
"5m": "5m",
"30m": "30m",
"Forever": "Forever"
} }
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "Mostrar siempre la ventana flotante, desactivar la barra lateral para todos los adaptadores de sitios", "Always display floating window, disable sidebar for all site adapters": "Mostrar siempre la ventana flotante, desactivar la barra lateral para todos los adaptadores de sitios",
"Allow ESC to close all floating windows": "Permitir que ESC cierre todas las ventanas flotantes", "Allow ESC to close all floating windows": "Permitir que ESC cierre todas las ventanas flotantes",
"Export All Data": "Exportar todos los datos", "Export All Data": "Exportar todos los datos",
"Import All Data": "Importar todos los datos" "Import All Data": "Importar todos los datos",
"Keep-Alive Time": "Tiempo de mantenimiento de la conexión",
"5m": "5m",
"30m": "30m",
"Forever": "Siempre"
} }
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "Toujours afficher la fenêtre flottante, désactiver la barre latérale pour tous les adaptateurs de site", "Always display floating window, disable sidebar for all site adapters": "Toujours afficher la fenêtre flottante, désactiver la barre latérale pour tous les adaptateurs de site",
"Allow ESC to close all floating windows": "Autoriser la touche ESC pour fermer toutes les fenêtres flottantes", "Allow ESC to close all floating windows": "Autoriser la touche ESC pour fermer toutes les fenêtres flottantes",
"Export All Data": "Exporter toutes les données", "Export All Data": "Exporter toutes les données",
"Import All Data": "Importer toutes les données" "Import All Data": "Importer toutes les données",
"Keep-Alive Time": "Temps de maintien de la connexion",
"5m": "5m",
"30m": "30m",
"Forever": "Toujours"
} }
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "Selalu tampilkan jendela mengambang, nonaktifkan sidebar untuk semua adapter situs", "Always display floating window, disable sidebar for all site adapters": "Selalu tampilkan jendela mengambang, nonaktifkan sidebar untuk semua adapter situs",
"Allow ESC to close all floating windows": "Izinkan ESC untuk menutup semua jendela mengambang", "Allow ESC to close all floating windows": "Izinkan ESC untuk menutup semua jendela mengambang",
"Export All Data": "Ekspor Semua Data", "Export All Data": "Ekspor Semua Data",
"Import All Data": "Impor Semua Data" "Import All Data": "Impor Semua Data",
"Keep-Alive Time": "Waktu Tetap Hidup",
"5m": "5m",
"30m": "30m",
"Forever": "Selamanya"
} }
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "Mostra sempre la finestra flottante, disabilita la barra laterale per tutti gli adattatori del sito", "Always display floating window, disable sidebar for all site adapters": "Mostra sempre la finestra flottante, disabilita la barra laterale per tutti gli adattatori del sito",
"Allow ESC to close all floating windows": "Consenti ESC per chiudere tutte le finestre flottanti", "Allow ESC to close all floating windows": "Consenti ESC per chiudere tutte le finestre flottanti",
"Export All Data": "Esporta tutti i dati", "Export All Data": "Esporta tutti i dati",
"Import All Data": "Importa tutti i dati" "Import All Data": "Importa tutti i dati",
"Keep-Alive Time": "Tempo di mantenimento",
"5m": "5m",
"30m": "30m",
"Forever": "Per sempre"
} }
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "常にフローティングウィンドウを表示し、すべてのサイトアダプターでサイドバーを無効にします", "Always display floating window, disable sidebar for all site adapters": "常にフローティングウィンドウを表示し、すべてのサイトアダプターでサイドバーを無効にします",
"Allow ESC to close all floating windows": "ESCキーですべてのフローティングウィンドウを閉じる", "Allow ESC to close all floating windows": "ESCキーですべてのフローティングウィンドウを閉じる",
"Export All Data": "すべてのデータをエクスポート", "Export All Data": "すべてのデータをエクスポート",
"Import All Data": "すべてのデータをインポート" "Import All Data": "すべてのデータをインポート",
"Keep-Alive Time": "Keep-Alive時間",
"5m": "5分",
"30m": "30分",
"Forever": "永久"
} }
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "항상 떠다니는 창을 표시하고 모든 사이트 어댑터의 사이드바를 비활성화합니다", "Always display floating window, disable sidebar for all site adapters": "항상 떠다니는 창을 표시하고 모든 사이트 어댑터의 사이드바를 비활성화합니다",
"Allow ESC to close all floating windows": "ESC를 눌러 모든 떠다니는 창을 닫도록 허용", "Allow ESC to close all floating windows": "ESC를 눌러 모든 떠다니는 창을 닫도록 허용",
"Export All Data": "모든 데이터 내보내기", "Export All Data": "모든 데이터 내보내기",
"Import All Data": "모든 데이터 가져오기" "Import All Data": "모든 데이터 가져오기",
"Keep-Alive Time": "Keep-Alive 시간",
"5m": "5분",
"30m": "30분",
"Forever": "영원히"
} }
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "Sempre exibir janela flutuante, desativar barra lateral para todos os adaptadores de site", "Always display floating window, disable sidebar for all site adapters": "Sempre exibir janela flutuante, desativar barra lateral para todos os adaptadores de site",
"Allow ESC to close all floating windows": "Permitir ESC para fechar todas as janelas flutuantes", "Allow ESC to close all floating windows": "Permitir ESC para fechar todas as janelas flutuantes",
"Export All Data": "Exportar Todos os Dados", "Export All Data": "Exportar Todos os Dados",
"Import All Data": "Importar Todos os Dados" "Import All Data": "Importar Todos os Dados",
"Keep-Alive Time": "Tempo de Manutenção de Conexão",
"5m": "5m",
"30m": "30m",
"Forever": "Para sempre"
} }
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "Всегда отображать плавающее окно, отключить боковую панель для всех адаптеров сайтов", "Always display floating window, disable sidebar for all site adapters": "Всегда отображать плавающее окно, отключить боковую панель для всех адаптеров сайтов",
"Allow ESC to close all floating windows": "Разрешить ESC для закрытия всех плавающих окон", "Allow ESC to close all floating windows": "Разрешить ESC для закрытия всех плавающих окон",
"Export All Data": "Экспорт всех данных", "Export All Data": "Экспорт всех данных",
"Import All Data": "Импорт всех данных" "Import All Data": "Импорт всех данных",
"Keep-Alive Time": "Время поддержания активности",
"5m": "5m",
"30m": "30m",
"Forever": "Вечно"
} }
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "Her zaman kayan pencereyi görüntüle, tüm site adaptörleri için kenar çubuğunu devre dışı bırak", "Always display floating window, disable sidebar for all site adapters": "Her zaman kayan pencereyi görüntüle, tüm site adaptörleri için kenar çubuğunu devre dışı bırak",
"Allow ESC to close all floating windows": "ESC tuşuyla tüm kayan pencereleri kapatmaya izin ver", "Allow ESC to close all floating windows": "ESC tuşuyla tüm kayan pencereleri kapatmaya izin ver",
"Export All Data": "Tüm Verileri Dışa Aktar", "Export All Data": "Tüm Verileri Dışa Aktar",
"Import All Data": "Tüm Verileri İçe Aktar" "Import All Data": "Tüm Verileri İçe Aktar",
"Keep-Alive Time": "Canlı Tutma Süresi",
"5m": "5m",
"30m": "30m",
"Forever": "Sonsuza dek"
} }
+1 -3
View File
@@ -77,7 +77,6 @@
"ChatGPT (GPT-4-8k)": "ChatGPT (GPT-4-8k)", "ChatGPT (GPT-4-8k)": "ChatGPT (GPT-4-8k)",
"ChatGPT (GPT-4-32k)": "ChatGPT (GPT-4-32k)", "ChatGPT (GPT-4-32k)": "ChatGPT (GPT-4-32k)",
"GPT-3.5": "GPT-3.5", "GPT-3.5": "GPT-3.5",
"Ollama API": "Ollama API",
"Custom Model": "自定义模型", "Custom Model": "自定义模型",
"Balanced": "平衡", "Balanced": "平衡",
"Creative": "有创造力", "Creative": "有创造力",
@@ -148,8 +147,7 @@
"Allow ESC to close all floating windows": "允许按ESC关闭所有浮动窗口", "Allow ESC to close all floating windows": "允许按ESC关闭所有浮动窗口",
"Export All Data": "导出所有数据", "Export All Data": "导出所有数据",
"Import All Data": "导入所有数据", "Import All Data": "导入所有数据",
"Temperature": "温度", "Keep-Alive Time": "保活时间",
"keep-alive Time": "保活时间",
"5m": "5分钟", "5m": "5分钟",
"30m": "半小时", "30m": "半小时",
"Forever": "永久" "Forever": "永久"
+5 -1
View File
@@ -146,5 +146,9 @@
"Always display floating window, disable sidebar for all site adapters": "總是顯示浮動視窗,停用所有網站適配器的側邊欄", "Always display floating window, disable sidebar for all site adapters": "總是顯示浮動視窗,停用所有網站適配器的側邊欄",
"Allow ESC to close all floating windows": "允許按 ESC 關閉所有浮動視窗", "Allow ESC to close all floating windows": "允許按 ESC 關閉所有浮動視窗",
"Export All Data": "匯出所有資料", "Export All Data": "匯出所有資料",
"Import All Data": "匯入所有資料" "Import All Data": "匯入所有資料",
"Keep-Alive Time": "保持連線時間",
"5m": "5 分鐘",
"30m": "30 分鐘",
"Forever": "永遠"
} }
+1 -7
View File
@@ -127,13 +127,7 @@ async function executeApi(session, port, config) {
config.customModelName, config.customModelName,
) )
} else if (ollamaApiModelKeys.includes(session.modelName)) { } else if (ollamaApiModelKeys.includes(session.modelName)) {
await generateAnswersWithOllamaApi( await generateAnswersWithOllamaApi(port, session.question, session)
port,
session.question,
session,
config.ollamaApiKey,
config.ollamaModelName,
)
} else if (azureOpenAiApiModelKeys.includes(session.modelName)) { } else if (azureOpenAiApiModelKeys.includes(session.modelName)) {
await generateAnswersWithAzureOpenaiApi(port, session.question, session) await generateAnswersWithAzureOpenaiApi(port, session.question, session)
} else if (claudeApiModelKeys.includes(session.modelName)) { } else if (claudeApiModelKeys.includes(session.modelName)) {
+2 -1
View File
@@ -251,7 +251,8 @@ export const defaultConfig = {
ollamaEndpoint: 'http://127.0.0.1:11434', ollamaEndpoint: 'http://127.0.0.1:11434',
ollamaModelName: 'llama3.1', ollamaModelName: 'llama3.1',
keepAliveTime: '5m', ollamaApiKey: '',
ollamaKeepAliveTime: '5m',
// advanced // advanced
-45
View File
@@ -1,7 +1,5 @@
import '../styles.scss'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { parseFloatWithClamp, parseIntWithClamp } from '../../utils/index.mjs' import { parseFloatWithClamp, parseIntWithClamp } from '../../utils/index.mjs'
import { isUsingOllamaModel } from '../../config/index.mjs'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs' import { Tab, TabList, TabPanel, Tabs } from 'react-tabs'
import Browser from 'webextension-polyfill' import Browser from 'webextension-polyfill'
@@ -58,49 +56,6 @@ function ApiParams({ config, updateConfig }) {
}} }}
/> />
</label> </label>
{isUsingOllamaModel(config) && (
<label>
{`${t('keep-alive Time')}: `}
<div className="label-group">
<label>
<input
type="radio"
name="keepAliveTime"
value="5m"
checked={config.keepAliveTime === '5m'}
onChange={(e) => {
updateConfig({ keepAliveTime: e.target.value })
}}
/>
{t('5m')}
</label>
<label>
<input
type="radio"
name="keepAliveTime"
value="30m"
checked={config.keepAliveTime === '30m'}
onChange={(e) => {
updateConfig({ keepAliveTime: e.target.value })
}}
/>
{t('30m')}
</label>
<label>
<input
type="radio"
name="keepAliveTime"
value="-1"
checked={config.keepAliveTime === '-1'}
onChange={(e) => {
updateConfig({ keepAliveTime: e.target.value })
}}
/>
{t('Forever')}
</label>
</div>
</label>
)}
</> </>
) )
} }
+41
View File
@@ -350,6 +350,47 @@ export function GeneralPart({ config, updateConfig }) {
}} }}
/> />
)} )}
{isUsingOllamaModel(config) && (
<div style={{ display: 'flex', gap: '10px' }}>
{t('Keep-Alive Time') + ':'}
<label>
<input
type="radio"
name="ollamaKeepAliveTime"
value="5m"
checked={config.ollamaKeepAliveTime === '5m'}
onChange={(e) => {
updateConfig({ ollamaKeepAliveTime: e.target.value })
}}
/>
{t('5m')}
</label>
<label>
<input
type="radio"
name="ollamaKeepAliveTime"
value="30m"
checked={config.ollamaKeepAliveTime === '30m'}
onChange={(e) => {
updateConfig({ ollamaKeepAliveTime: e.target.value })
}}
/>
{t('30m')}
</label>
<label>
<input
type="radio"
name="ollamaKeepAliveTime"
value="-1"
checked={config.ollamaKeepAliveTime === '-1'}
onChange={(e) => {
updateConfig({ ollamaKeepAliveTime: e.target.value })
}}
/>
{t('Forever')}
</label>
</div>
)}
{isUsingOllamaModel(config) && ( {isUsingOllamaModel(config) && (
<input <input
type="text" type="text"
-15
View File
@@ -23,11 +23,6 @@
--active-color: #eaecf0; --active-color: #eaecf0;
} }
#app {
max-width: 600px;
margin: 0 auto;
}
.container-page-mode { .container-page-mode {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -63,7 +58,6 @@
} }
.footer { .footer {
max-width: 580px;
width: 90%; width: 90%;
position: fixed; position: fixed;
bottom: 10px; bottom: 10px;
@@ -94,12 +88,3 @@
background: var(--active-color); background: var(--active-color);
} }
} }
.label-group {
display: flex;
align-items: center;
}
.label-group label {
margin-right: 10px;
}
+27 -73
View File
@@ -1,84 +1,38 @@
// ollama api version
// There is a lot of duplicated code here, but it is very easy to refactor.
// The current state is mainly convenient for making targeted changes at any time,
// and it has not yet had a negative impact on maintenance.
// If necessary, I will refactor.
import { getUserConfig } from '../../config/index.mjs' import { getUserConfig } from '../../config/index.mjs'
import { fetchSSE } from '../../utils/fetch-ollama.mjs' import { generateAnswersWithChatgptApiCompat } from './openai-api.mjs'
import { getConversationPairs } from '../../utils/get-conversation-pairs.mjs'
import { isEmpty } from 'lodash-es'
import { pushRecord, setAbortController } from './shared.mjs'
/** /**
* @param {Browser.Runtime.Port} port * @param {Browser.Runtime.Port} port
* @param {string} question * @param {string} question
* @param {Session} session * @param {Session} session
* @param {string} apiKey
* @param {string} modelName
*/ */
export async function generateAnswersWithOllamaApi(port, question, session, apiKey, modelName) { export async function generateAnswersWithOllamaApi(port, question, session) {
const { controller, messageListener, disconnectListener } = setAbortController(port)
const config = await getUserConfig() const config = await getUserConfig()
const prompt = getConversationPairs( return generateAnswersWithChatgptApiCompat(
session.conversationRecords.slice(-config.maxConversationContextLength), config.ollamaEndpoint + '/v1',
false, port,
) question,
// prompt.unshift({ role: 'system', content: await getOllamaApiPromptBase() }) session,
prompt.push({ role: 'user', content: question }) config.ollamaApiKey,
const apiUrl = config.ollamaEndpoint 'ollamaModel',
{
let answer = '' model: config.ollamaModelName,
let finished = false
const finish = () => {
finished = true
pushRecord(session, question, answer)
console.debug('conversation history', { content: session.conversationRecords })
port.postMessage({ answer: null, done: true, session: session })
}
await fetchSSE(`${apiUrl}/api/chat`, {
method: 'POST',
signal: controller.signal,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${apiKey}`,
}, },
body: JSON.stringify({ ).then(() =>
messages: prompt, fetch(config.ollamaEndpoint + '/api/generate', {
model: modelName, method: 'POST',
stream: true, headers: {
max_tokens: config.maxResponseTokenLength, 'Content-Type': 'application/json',
temperature: config.temperature, Authorization: `Bearer ${config.ollamaApiKey}`,
keep_alive: config.keepAliveTime === '-1' ? -1 : config.keepAliveTime, },
body: JSON.stringify({
model: config.ollamaModelName,
prompt: 't',
options: {
num_predict: 1,
},
keep_alive: config.ollamaKeepAliveTime === '-1' ? -1 : config.ollamaKeepAliveTime,
}),
}), }),
onMessage(message) { )
console.debug('sse message', message)
if (finished) return
let data = message
const delta = data.message?.content
if (delta) {
answer += delta
port.postMessage({ answer: answer, done: false, session: null })
}
if (data.done_reason) {
finish()
return
}
},
async onStart() {},
async onEnd() {
port.postMessage({ done: true })
port.onMessage.removeListener(messageListener)
port.onDisconnect.removeListener(disconnectListener)
},
async onError(resp) {
port.onMessage.removeListener(messageListener)
port.onDisconnect.removeListener(disconnectListener)
if (resp instanceof Error) throw resp
const error = await resp.json().catch(() => ({}))
throw new Error(!isEmpty(error) ? JSON.stringify(error) : `${resp.status} ${resp.statusText}`)
},
})
} }
+2
View File
@@ -125,6 +125,7 @@ export async function generateAnswersWithChatgptApiCompat(
session, session,
apiKey, apiKey,
modelName, modelName,
extraBody = {},
) { ) {
const { controller, messageListener, disconnectListener } = setAbortController(port) const { controller, messageListener, disconnectListener } = setAbortController(port)
@@ -157,6 +158,7 @@ export async function generateAnswersWithChatgptApiCompat(
stream: true, stream: true,
max_tokens: config.maxResponseTokenLength, max_tokens: config.maxResponseTokenLength,
temperature: config.temperature, temperature: config.temperature,
...extraBody,
}), }),
onMessage(message) { onMessage(message) {
console.debug('sse message', message) console.debug('sse message', message)
-27
View File
@@ -1,27 +0,0 @@
export async function fetchSSE(resource, options) {
const { onMessage, onStart, onEnd, onError, ...fetchOptions } = options
const resp = await fetch(resource, fetchOptions).catch(async (err) => {
await onError(err)
})
if (!resp) return
if (!resp.ok) {
await onError(resp)
return
}
let hasStarted = false
const reader = resp.body.getReader()
let result
while (!(result = await reader.read()).done) {
const chunk = result.value
const str = new TextDecoder().decode(chunk)
if (!hasStarted) {
const str = new TextDecoder().decode(chunk)
hasStarted = true
await onStart(str)
}
let data = JSON.parse(str)
onMessage(data)
if (data.done) break
}
await onEnd()
}
-1
View File
@@ -33,7 +33,6 @@ export async function fetchSSE(resource, options) {
console.debug('not common response', error) console.debug('not common response', error)
} }
if (fakeSseData) { if (fakeSseData) {
console.log('FAKE')
parser.feed(new TextEncoder().encode(fakeSseData)) parser.feed(new TextEncoder().encode(fakeSseData))
break break
} }