完成全部配置的保存
This commit is contained in:
parent
05080e2b72
commit
3d372dafae
@ -15,6 +15,7 @@ import { setDefaultCss } from './hook/css';
|
||||
import { pinkLog } from './views/setting/util';
|
||||
import { acquireVsCodeApi, useMessageBridge } from './api/message-bridge';
|
||||
import { connectionArgs, connectionMethods, connectionResult, doConnect } from './views/connect/connection';
|
||||
import { loadSetting } from './hook/setting';
|
||||
|
||||
const bridge = useMessageBridge();
|
||||
|
||||
@ -25,21 +26,10 @@ bridge.addCommandListener('hello', data => {
|
||||
}, { once: true });
|
||||
|
||||
|
||||
// 发送消息
|
||||
const sendPing = () => {
|
||||
bridge.postMessage({
|
||||
command: 'ping',
|
||||
data: { timestamp: Date.now() }
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
// 初始化 css
|
||||
setDefaultCss();
|
||||
|
||||
// 初始化 设置
|
||||
|
||||
document.addEventListener('click', () => {
|
||||
Connection.showPanel = false;
|
||||
});
|
||||
@ -58,6 +48,9 @@ onMounted(() => {
|
||||
}, { once: true });
|
||||
|
||||
setTimeout(() => {
|
||||
// 初始化 设置
|
||||
loadSetting();
|
||||
|
||||
doConnect();
|
||||
}, 200);
|
||||
}
|
||||
|
@ -97,10 +97,28 @@ class MessageBridge {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 注册一个命令的执行器
|
||||
* @returns
|
||||
* @description 注册一个命令的执行器(支持一次性或持久监听)
|
||||
* @example
|
||||
* // 基本用法(持久监听)
|
||||
* const removeListener = bridge.addCommandListener('message', (data) => {
|
||||
* console.log('收到消息:', data.msg.text);
|
||||
* }, { once: false });
|
||||
*
|
||||
* // 稍后取消监听
|
||||
* removeListener();
|
||||
*
|
||||
* @example
|
||||
* // 一次性监听(自动移除)
|
||||
* bridge.addCommandListener('connect', (data) => {
|
||||
* const { code, msg } = data;
|
||||
* console.log(`连接结果: ${code === 200 ? '成功' : '失败'}`);
|
||||
* }, { once: true });
|
||||
*/
|
||||
public addCommandListener(command: string, commandHandler: CommandHandler, option: AddCommandListenerOption) {
|
||||
public addCommandListener(
|
||||
command: string,
|
||||
commandHandler: CommandHandler,
|
||||
option: AddCommandListenerOption
|
||||
): () => boolean {
|
||||
if (!this.handlers.has(command)) {
|
||||
this.handlers.set(command, new Set<CommandHandler>());
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
>
|
||||
<span>
|
||||
<span :class="`iconfont ${tab.icon}`"></span>
|
||||
<span>{{ tab.name }}</span>
|
||||
<span class="tab-name">{{ tab.name }}</span>
|
||||
</span>
|
||||
<span
|
||||
class="iconfont icon-close"
|
||||
@ -33,8 +33,6 @@
|
||||
<div class="main-panel">
|
||||
<router-view />
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -83,6 +81,7 @@ defineComponent({ name: 'main-panel' });
|
||||
}
|
||||
|
||||
.tabs-container .tab {
|
||||
white-space: nowrap;
|
||||
margin: 5px;
|
||||
font-size: 13px;
|
||||
width: 120px;
|
||||
@ -101,6 +100,12 @@ defineComponent({ name: 'main-panel' });
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tabs-container .tab .tab-name {
|
||||
max-width: 70px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.tabs-container .tab:hover {
|
||||
background-color: var(--input-active-background);
|
||||
}
|
||||
|
@ -4,6 +4,9 @@ import Resource from './resource/index.vue';
|
||||
import Chat from './chat/index.vue';
|
||||
import Prompt from './prompt/index.vue';
|
||||
import Tool from './tool/index.vue';
|
||||
import I18n from '@/i18n/index';
|
||||
|
||||
const { t } = I18n.global;
|
||||
|
||||
interface Tab {
|
||||
name: string;
|
||||
@ -18,16 +21,14 @@ export const debugModes = [
|
||||
]
|
||||
|
||||
// TODO: 实现对于 tabs 这个数据的可持久化
|
||||
export const tabs = reactive({
|
||||
export const tabs = reactive<{
|
||||
content: Tab[]
|
||||
activeIndex: number
|
||||
activeTab: Tab
|
||||
}>({
|
||||
content: [
|
||||
{
|
||||
name: '空白测试 1',
|
||||
icon: 'icon-blank',
|
||||
type: 'blank',
|
||||
component: undefined,
|
||||
storage: {}
|
||||
}
|
||||
] as Tab[],
|
||||
createTab('blank', 1)
|
||||
],
|
||||
activeIndex: 0,
|
||||
get activeTab() {
|
||||
return this.content[this.activeIndex];
|
||||
@ -36,14 +37,28 @@ export const tabs = reactive({
|
||||
|
||||
let tabCounter = 1;
|
||||
|
||||
export function addNewTab() {
|
||||
const newTab = {
|
||||
name: `空白测试 ${++ tabCounter}`,
|
||||
function createTab(type: string, index: number): Tab {
|
||||
let customName: string | null = null;
|
||||
|
||||
return {
|
||||
get name() {
|
||||
if (customName !== null) {
|
||||
return customName;
|
||||
}
|
||||
return t('blank-test') + ` ${index}`;
|
||||
},
|
||||
set name(value: string) {
|
||||
customName = value; // 允许外部修改 name
|
||||
},
|
||||
icon: 'icon-blank',
|
||||
type: 'blank',
|
||||
type,
|
||||
component: undefined,
|
||||
storage: {}
|
||||
storage: {},
|
||||
};
|
||||
}
|
||||
|
||||
export function addNewTab() {
|
||||
const newTab = createTab('blank', ++tabCounter);
|
||||
tabs.content.push(newTab);
|
||||
tabs.activeIndex = tabs.content.length - 1;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<div class="left">
|
||||
<h2>
|
||||
<span class="iconfont icon-file"></span>
|
||||
资源模块
|
||||
{{ t("resources") + t("module") }}
|
||||
</h2>
|
||||
<h3><code>resources/templates/list</code></h3>
|
||||
|
||||
@ -26,10 +26,13 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineProps } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import ResourceTemplates from './resource-templates.vue';
|
||||
import ResourceReader from './resouce-reader.vue';
|
||||
import ResourceLogger from './resource-logger.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps({
|
||||
tabId: {
|
||||
type: Number,
|
||||
|
@ -1,14 +1,48 @@
|
||||
import { useMessageBridge } from "@/api/message-bridge";
|
||||
|
||||
import { llmManager, llms } from "@/views/setting/llm";
|
||||
import { pinkLog } from "@/views/setting/util";
|
||||
import I18n from '@/i18n/index';
|
||||
|
||||
export function loadSetting() {
|
||||
const bridge = useMessageBridge();
|
||||
bridge.addCommandListener('setting/load', () => {
|
||||
|
||||
bridge.addCommandListener('setting/load', data => {
|
||||
const persistConfig = data.msg;
|
||||
|
||||
llmManager.currentModelIndex = persistConfig.MODEL_INDEX;
|
||||
I18n.global.locale.value = persistConfig.LANG;
|
||||
|
||||
persistConfig.LLM_INFO.forEach((element: any) => {
|
||||
llms.push(element);
|
||||
});
|
||||
|
||||
}, { once: true });
|
||||
|
||||
bridge.postMessage({
|
||||
command: 'setting/load'
|
||||
});
|
||||
}
|
||||
|
||||
export function saveSetting() {
|
||||
export function saveSetting(saveHandler?: () => void) {
|
||||
const bridge = useMessageBridge();
|
||||
|
||||
const saveConfig = {
|
||||
MODEL_INDEX: llmManager.currentModelIndex,
|
||||
LLM_INFO: JSON.parse(JSON.stringify(llms)),
|
||||
LANG: I18n.global.locale.value
|
||||
};
|
||||
|
||||
bridge.addCommandListener('setting/save', data => {
|
||||
const saveStatusCode = data.code;
|
||||
pinkLog('配置保存状态:' + saveStatusCode);
|
||||
|
||||
if (saveHandler) {
|
||||
saveHandler();
|
||||
}
|
||||
}, { once: true });
|
||||
|
||||
bridge.postMessage({
|
||||
command: 'setting/save',
|
||||
data: saveConfig
|
||||
});
|
||||
}
|
@ -109,9 +109,12 @@
|
||||
"reset": "إعادة تعيين",
|
||||
"read-resource": "قراءة الموارد",
|
||||
"enter": "إدخال",
|
||||
"refresh": "تحديث",
|
||||
"finish-refresh": "تم التحديث",
|
||||
"blank-test": "اختبار فارغ",
|
||||
"connect.appearance.reconnect": "إعادة الاتصال",
|
||||
"connect.appearance.connect": "اتصال",
|
||||
"response": "الاستجابة",
|
||||
"read-prompt": "استخراج الكلمات الرئيسية",
|
||||
"execute-tool": "تشغيل الأداة"
|
||||
"refresh": "تحديث",
|
||||
"read-prompt": "قراءة المطالبة",
|
||||
"execute-tool": "تشغيل",
|
||||
"save": "حفظ"
|
||||
}
|
@ -109,9 +109,12 @@
|
||||
"reset": "Zurücksetzen",
|
||||
"read-resource": "Ressourcen lesen",
|
||||
"enter": "Eingabe",
|
||||
"refresh": "Aktualisieren",
|
||||
"finish-refresh": "Aktualisierung abgeschlossen",
|
||||
"blank-test": "Leertest",
|
||||
"connect.appearance.reconnect": "Neuverbindung",
|
||||
"connect.appearance.connect": "Verbindung",
|
||||
"response": "Antwort",
|
||||
"read-prompt": "Stichwörter extrahieren",
|
||||
"execute-tool": "Werkzeug ausführen"
|
||||
"refresh": "Aktualisieren",
|
||||
"read-prompt": "Prompt lesen",
|
||||
"execute-tool": "Ausführen",
|
||||
"save": "Speichern"
|
||||
}
|
@ -109,9 +109,12 @@
|
||||
"reset": "Reset",
|
||||
"read-resource": "Read resources",
|
||||
"enter": "Input",
|
||||
"refresh": "Refresh",
|
||||
"finish-refresh": "Refresh completed",
|
||||
"blank-test": "Blank test",
|
||||
"connect.appearance.reconnect": "Reconnect",
|
||||
"connect.appearance.connect": "Connection",
|
||||
"response": "Response",
|
||||
"read-prompt": "Extract keywords",
|
||||
"execute-tool": "Run tool"
|
||||
"refresh": "Refresh",
|
||||
"read-prompt": "Read prompt",
|
||||
"execute-tool": "Run",
|
||||
"save": "Save"
|
||||
}
|
@ -109,9 +109,12 @@
|
||||
"reset": "Réinitialiser",
|
||||
"read-resource": "Lire les ressources",
|
||||
"enter": "Entrée",
|
||||
"refresh": "Rafraîchir",
|
||||
"finish-refresh": "Actualisation terminée",
|
||||
"blank-test": "Test vide",
|
||||
"connect.appearance.reconnect": "Reconnexion",
|
||||
"connect.appearance.connect": "Connexion",
|
||||
"response": "Réponse",
|
||||
"read-prompt": "Extraire des mots-clés",
|
||||
"execute-tool": "Exécuter l'outil"
|
||||
"refresh": "Rafraîchir",
|
||||
"read-prompt": "Lire l'invite",
|
||||
"execute-tool": "Exécuter",
|
||||
"save": "Enregistrer"
|
||||
}
|
@ -109,9 +109,12 @@
|
||||
"reset": "リセット",
|
||||
"read-resource": "リソースを読み込む",
|
||||
"enter": "入力",
|
||||
"refresh": "更新",
|
||||
"finish-refresh": "更新が完了しました",
|
||||
"blank-test": "空白テスト",
|
||||
"connect.appearance.reconnect": "再接続",
|
||||
"connect.appearance.connect": "接続",
|
||||
"response": "応答",
|
||||
"read-prompt": "キーワードを抽出",
|
||||
"execute-tool": "ツールを実行"
|
||||
"refresh": "更新",
|
||||
"read-prompt": "プロンプトを読み取る",
|
||||
"execute-tool": "実行",
|
||||
"save": "保存"
|
||||
}
|
@ -109,9 +109,12 @@
|
||||
"reset": "재설정",
|
||||
"read-resource": "리소스 읽기",
|
||||
"enter": "입력",
|
||||
"refresh": "새로 고침",
|
||||
"finish-refresh": "새로 고침 완료",
|
||||
"blank-test": "빈 테스트",
|
||||
"connect.appearance.reconnect": "재연결",
|
||||
"connect.appearance.connect": "연결",
|
||||
"response": "응답",
|
||||
"read-prompt": "키워드 추출",
|
||||
"execute-tool": "도구 실행"
|
||||
"refresh": "새로 고침",
|
||||
"read-prompt": "프롬프트 읽기",
|
||||
"execute-tool": "실행",
|
||||
"save": "저장"
|
||||
}
|
@ -109,9 +109,12 @@
|
||||
"reset": "Сброс",
|
||||
"read-resource": "Чтение ресурсов",
|
||||
"enter": "Ввод",
|
||||
"refresh": "Обновить",
|
||||
"finish-refresh": "Обновление завершено",
|
||||
"blank-test": "Пустой тест",
|
||||
"connect.appearance.reconnect": "Переподключение",
|
||||
"connect.appearance.connect": "Соединение",
|
||||
"response": "Ответ",
|
||||
"read-prompt": "Извлечь ключевые слова",
|
||||
"execute-tool": "Запустить инструмент"
|
||||
"refresh": "Обновить",
|
||||
"read-prompt": "Чтение подсказки",
|
||||
"execute-tool": "Запуск",
|
||||
"save": "Сохранить"
|
||||
}
|
@ -109,9 +109,12 @@
|
||||
"reset": "重置",
|
||||
"read-resource": "读取资源",
|
||||
"enter": "输入",
|
||||
"refresh": "刷新",
|
||||
"finish-refresh": "刷新完成",
|
||||
"blank-test": "空白测试",
|
||||
"connect.appearance.reconnect": "重新连接",
|
||||
"connect.appearance.connect": "连接",
|
||||
"response": "响应",
|
||||
"read-prompt": "提取提词",
|
||||
"execute-tool": "运行工具"
|
||||
"refresh": "刷新",
|
||||
"read-prompt": "读取 prompt",
|
||||
"execute-tool": "运行",
|
||||
"save": "保存"
|
||||
}
|
@ -109,9 +109,12 @@
|
||||
"reset": "重置",
|
||||
"read-resource": "讀取資源",
|
||||
"enter": "輸入",
|
||||
"refresh": "重新整理",
|
||||
"finish-refresh": "刷新完成",
|
||||
"blank-test": "空白測試",
|
||||
"connect.appearance.reconnect": "重新連線",
|
||||
"connect.appearance.connect": "連接",
|
||||
"response": "響應",
|
||||
"read-prompt": "提取關鍵詞",
|
||||
"execute-tool": "執行工具"
|
||||
"refresh": "重新整理",
|
||||
"read-prompt": "讀取提示",
|
||||
"execute-tool": "執行",
|
||||
"save": "儲存"
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { debugModes, tabs } from '@/components/main-panel/panel';
|
||||
import { defineComponent, markRaw } from 'vue';
|
||||
import { defineComponent, markRaw, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { connectionResult } from '../connect/connection';
|
||||
import { ElMessage } from 'element-plus';
|
||||
@ -33,22 +33,22 @@ const { t } = useI18n();
|
||||
const debugOptions = [
|
||||
{
|
||||
icon: 'icon-file',
|
||||
name: t("resources"),
|
||||
name: computed(() => t("resources")),
|
||||
ident: 'resources'
|
||||
},
|
||||
{
|
||||
icon: 'icon-chat',
|
||||
name: t("prompts"),
|
||||
name: computed(() => t("prompts")),
|
||||
ident: 'prompts'
|
||||
},
|
||||
{
|
||||
icon: 'icon-tool',
|
||||
name: t("tools"),
|
||||
name: computed(() => t("tools")),
|
||||
ident: 'tool'
|
||||
},
|
||||
{
|
||||
icon: 'icon-robot',
|
||||
name: t("interaction-test"),
|
||||
name: computed(() => t("interaction-test")),
|
||||
ident: 'interaction'
|
||||
}
|
||||
];
|
||||
@ -60,7 +60,9 @@ function chooseDebugMode(index: number) {
|
||||
const activeTab = tabs.activeTab;
|
||||
activeTab.component = markRaw(debugModes[index]);
|
||||
activeTab.icon = debugOptions[index].icon;
|
||||
activeTab.name = debugOptions[index].name;
|
||||
|
||||
// 此处可以这么做是因为这个操作过后 activeTab 绑定的 tab 的 name 就不会再被进行赋值操作了
|
||||
activeTab.name = debugOptions[index].name as any;
|
||||
} else {
|
||||
const message = t('warning.click-to-connect')
|
||||
.replace('$1', t('connect'));
|
||||
|
@ -34,7 +34,9 @@
|
||||
<span class="option-title">{{ t('model') }}</span>
|
||||
</span>
|
||||
<div style="width: 160px;">
|
||||
<el-select name="language-setting" class="language-setting"
|
||||
<el-select
|
||||
v-if="llms[llmManager.currentModelIndex]"
|
||||
name="language-setting" class="language-setting"
|
||||
v-model="llms[llmManager.currentModelIndex].userModel"
|
||||
@change="onmodelchange"
|
||||
>
|
||||
@ -54,6 +56,7 @@
|
||||
</span>
|
||||
<div style="width: 240px;">
|
||||
<el-input
|
||||
v-if="llms[llmManager.currentModelIndex]"
|
||||
v-model="llms[llmManager.currentModelIndex].baseUrl"
|
||||
placeholder="https://"
|
||||
/>
|
||||
@ -67,12 +70,21 @@
|
||||
</span>
|
||||
<div style="width: 240px;">
|
||||
<el-input
|
||||
v-if="llms[llmManager.currentModelIndex]"
|
||||
v-model="llms[llmManager.currentModelIndex].userToken"
|
||||
show-password
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="setting-save-container">
|
||||
<el-button type="primary" @click="saveLlmSetting">
|
||||
{{ t('save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
@ -81,14 +93,25 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import { llmManager, llms, onmodelchange } from './llm';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { saveSetting } from '@/hook/setting';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
defineComponent({ name: 'api' });
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
function saveLlmSetting() {
|
||||
saveSetting(() => {
|
||||
ElMessage({
|
||||
message: '成功保存',
|
||||
type: 'success'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.setting-save-container {
|
||||
margin: 5px;
|
||||
}
|
||||
</style>
|
@ -21,6 +21,7 @@
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { languageSetting } from './language';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { saveSetting } from '@/hook/setting';
|
||||
|
||||
defineComponent({ name: 'appearance' });
|
||||
|
||||
@ -34,6 +35,8 @@ function onlanguagechange(code: string) {
|
||||
currentLanguage.value = option.text;
|
||||
}
|
||||
// languageDialogShow.value = true;
|
||||
|
||||
saveSetting();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -1,104 +1,13 @@
|
||||
import { reactive } from 'vue';
|
||||
import { pinkLog } from './util';
|
||||
import { saveSetting } from '@/hook/setting';
|
||||
|
||||
export const llms = reactive([
|
||||
{
|
||||
id: 'deepseek',
|
||||
name: 'DeepSeek',
|
||||
baseUrl: 'https://api.deepseek.com/v1',
|
||||
models: ['deepseek-chat', 'deepseek-coder', 'deepseek-math'],
|
||||
icon: '/images/deepseek.com.ico',
|
||||
provider: 'DeepSeek',
|
||||
isOpenAICompatible: true,
|
||||
description: '深度求索推出的大模型,擅长中文和代码',
|
||||
website: 'https://www.deepseek.com',
|
||||
userToken: '',
|
||||
userModel: 'deepseek-chat'
|
||||
},
|
||||
{
|
||||
id: 'openai',
|
||||
name: 'OpenAI',
|
||||
baseUrl: 'https://api.openai.com/v1',
|
||||
models: ['gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo'],
|
||||
icon: '/images/openai.com.ico',
|
||||
provider: 'OpenAI',
|
||||
isOpenAICompatible: true,
|
||||
description: 'OpenAI官方API',
|
||||
website: 'https://openai.com',
|
||||
userToken: '',
|
||||
userModel: 'gpt-4-turbo'
|
||||
},
|
||||
{
|
||||
id: 'mistral',
|
||||
name: 'Mistral',
|
||||
baseUrl: 'https://api.mistral.ai/v1',
|
||||
models: ['mistral-tiny', 'mistral-small', 'mistral-medium'],
|
||||
icon: '/images/mistral.ai.ico',
|
||||
provider: 'Mistral AI',
|
||||
isOpenAICompatible: true,
|
||||
description: '欧洲开源大模型代表',
|
||||
website: 'https://mistral.ai',
|
||||
userToken: '',
|
||||
userModel: 'mistral-tiny'
|
||||
},
|
||||
{
|
||||
id: 'ollama',
|
||||
name: 'Ollama (Local)',
|
||||
baseUrl: 'http://localhost:11434/v1',
|
||||
models: ['llama2', 'mistral', 'codellama'],
|
||||
icon: '/images/ollama.png',
|
||||
provider: 'Ollama',
|
||||
isOpenAICompatible: true,
|
||||
description: '本地运行的大模型',
|
||||
website: 'https://ollama.com',
|
||||
userToken: '',
|
||||
userModel: 'llama2'
|
||||
},
|
||||
{
|
||||
id: 'groq',
|
||||
name: 'Groq',
|
||||
baseUrl: 'https://api.groq.com/openai/v1',
|
||||
models: ['mixtral-8x7b-32768', 'llama2-70b-4096'],
|
||||
icon: '/images/grok.com.png',
|
||||
provider: 'Groq',
|
||||
isOpenAICompatible: true,
|
||||
description: '超高速推理API',
|
||||
website: 'https://groq.com',
|
||||
userToken: '',
|
||||
userModel: 'mixtral-8x7b-32768'
|
||||
},
|
||||
{
|
||||
id: 'perplexity',
|
||||
name: 'Perplexity',
|
||||
baseUrl: 'https://api.perplexity.ai/v1',
|
||||
models: ['pplx-7b-online', 'pplx-70b-online'],
|
||||
icon: '/images/perplexity.ai.ico',
|
||||
provider: 'Perplexity AI',
|
||||
isOpenAICompatible: true,
|
||||
description: '联网搜索增强的大模型',
|
||||
website: 'https://www.perplexity.ai',
|
||||
userToken: '',
|
||||
userModel: 'pplx-7b-online'
|
||||
},
|
||||
{
|
||||
id: 'kimi',
|
||||
name: 'Kimi Chat',
|
||||
baseUrl: 'https://api.moonshot.cn/v1',
|
||||
models: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k'],
|
||||
icon: '/images/kimichat.cn.png',
|
||||
provider: '月之暗面 (Moonshot AI)',
|
||||
isOpenAICompatible: true,
|
||||
description: '支持超长上下文的中文大模型,上下文窗口高达128K',
|
||||
website: 'https://kimi.moonshot.cn',
|
||||
userToken: '',
|
||||
userModel: 'moonshot-v1-8k'
|
||||
}
|
||||
]);
|
||||
export const llms = reactive<any[]>([]);
|
||||
|
||||
export const llmManager = reactive({
|
||||
currentModelIndex: 0,
|
||||
});
|
||||
|
||||
export function onmodelchange() {
|
||||
console.log();
|
||||
|
||||
pinkLog('切换模型到:' + llms[llmManager.currentModelIndex].id);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { reactive } from 'vue';
|
||||
import { reactive, computed } from 'vue';
|
||||
|
||||
import I18n from '@/i18n/index';
|
||||
|
||||
@ -13,11 +13,11 @@ export const settingSections = reactive({
|
||||
},
|
||||
{
|
||||
value: 'general',
|
||||
label: t('general-setting')
|
||||
label: computed(() => t('general-setting'))
|
||||
},
|
||||
{
|
||||
value: 'appearance',
|
||||
label: t('appearance-setting')
|
||||
label: computed(() => t('appearance-setting'))
|
||||
}
|
||||
]
|
||||
});
|
||||
|
93
test/src/llm.ts
Normal file
93
test/src/llm.ts
Normal file
@ -0,0 +1,93 @@
|
||||
export const llms = [
|
||||
{
|
||||
id: 'deepseek',
|
||||
name: 'DeepSeek',
|
||||
baseUrl: 'https://api.deepseek.com/v1',
|
||||
models: ['deepseek-chat', 'deepseek-coder', 'deepseek-math'],
|
||||
icon: '/images/deepseek.com.ico',
|
||||
provider: 'DeepSeek',
|
||||
isOpenAICompatible: true,
|
||||
description: '深度求索推出的大模型,擅长中文和代码',
|
||||
website: 'https://www.deepseek.com',
|
||||
userToken: '',
|
||||
userModel: 'deepseek-chat'
|
||||
},
|
||||
{
|
||||
id: 'openai',
|
||||
name: 'OpenAI',
|
||||
baseUrl: 'https://api.openai.com/v1',
|
||||
models: ['gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo'],
|
||||
icon: '/images/openai.com.ico',
|
||||
provider: 'OpenAI',
|
||||
isOpenAICompatible: true,
|
||||
description: 'OpenAI官方API',
|
||||
website: 'https://openai.com',
|
||||
userToken: '',
|
||||
userModel: 'gpt-4-turbo'
|
||||
},
|
||||
{
|
||||
id: 'mistral',
|
||||
name: 'Mistral',
|
||||
baseUrl: 'https://api.mistral.ai/v1',
|
||||
models: ['mistral-tiny', 'mistral-small', 'mistral-medium'],
|
||||
icon: '/images/mistral.ai.ico',
|
||||
provider: 'Mistral AI',
|
||||
isOpenAICompatible: true,
|
||||
description: '欧洲开源大模型代表',
|
||||
website: 'https://mistral.ai',
|
||||
userToken: '',
|
||||
userModel: 'mistral-tiny'
|
||||
},
|
||||
{
|
||||
id: 'ollama',
|
||||
name: 'Ollama (Local)',
|
||||
baseUrl: 'http://localhost:11434/v1',
|
||||
models: ['llama2', 'mistral', 'codellama'],
|
||||
icon: '/images/ollama.png',
|
||||
provider: 'Ollama',
|
||||
isOpenAICompatible: true,
|
||||
description: '本地运行的大模型',
|
||||
website: 'https://ollama.com',
|
||||
userToken: '',
|
||||
userModel: 'llama2'
|
||||
},
|
||||
{
|
||||
id: 'groq',
|
||||
name: 'Groq',
|
||||
baseUrl: 'https://api.groq.com/openai/v1',
|
||||
models: ['mixtral-8x7b-32768', 'llama2-70b-4096'],
|
||||
icon: '/images/grok.com.png',
|
||||
provider: 'Groq',
|
||||
isOpenAICompatible: true,
|
||||
description: '超高速推理API',
|
||||
website: 'https://groq.com',
|
||||
userToken: '',
|
||||
userModel: 'mixtral-8x7b-32768'
|
||||
},
|
||||
{
|
||||
id: 'perplexity',
|
||||
name: 'Perplexity',
|
||||
baseUrl: 'https://api.perplexity.ai/v1',
|
||||
models: ['pplx-7b-online', 'pplx-70b-online'],
|
||||
icon: '/images/perplexity.ai.ico',
|
||||
provider: 'Perplexity AI',
|
||||
isOpenAICompatible: true,
|
||||
description: '联网搜索增强的大模型',
|
||||
website: 'https://www.perplexity.ai',
|
||||
userToken: '',
|
||||
userModel: 'pplx-7b-online'
|
||||
},
|
||||
{
|
||||
id: 'kimi',
|
||||
name: 'Kimi Chat',
|
||||
baseUrl: 'https://api.moonshot.cn/v1',
|
||||
models: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k'],
|
||||
icon: '/images/kimichat.cn.png',
|
||||
provider: '月之暗面 (Moonshot AI)',
|
||||
isOpenAICompatible: true,
|
||||
description: '支持超长上下文的中文大模型,上下文窗口高达128K',
|
||||
website: 'https://kimi.moonshot.cn',
|
||||
userToken: '',
|
||||
userModel: 'moonshot-v1-8k'
|
||||
}
|
||||
];
|
@ -1,6 +1,7 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import { llms } from './llm';
|
||||
|
||||
function getConfigurationPath() {
|
||||
// 如果是 vscode 插件下,则修改为 ~/.openmcp/config.json
|
||||
@ -16,17 +17,23 @@ function getConfigurationPath() {
|
||||
return 'config.json';
|
||||
}
|
||||
|
||||
function getDefaultLanguage() {
|
||||
if (process.env.VSCODE_PID) {
|
||||
// TODO: 获取 vscode 内部的语言
|
||||
|
||||
}
|
||||
return 'zh';
|
||||
}
|
||||
|
||||
interface IConfig {
|
||||
MODEL_BASE_URL: string;
|
||||
MODEL_NAME: string;
|
||||
API_TOKEN: string;
|
||||
MODEL_INDEX: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const DEFAULT_CONFIG: IConfig = {
|
||||
MODEL_BASE_URL: '',
|
||||
MODEL_NAME: '',
|
||||
API_TOKEN: ''
|
||||
MODEL_INDEX: 0,
|
||||
LLM_INFO: llms,
|
||||
LANG: getDefaultLanguage()
|
||||
};
|
||||
|
||||
function createConfig(): IConfig {
|
||||
|
Loading…
x
Reference in New Issue
Block a user