diff --git a/setting/chat.go b/setting/chat.go index bb8a99771939..855cf839ecd9 100644 --- a/setting/chat.go +++ b/setting/chat.go @@ -1,10 +1,6 @@ package setting -import ( - "encoding/json" - - "github.com/QuantumNous/new-api/common" -) +import "github.com/QuantumNous/new-api/common" var Chats = []map[string]string{ //{ @@ -25,6 +21,9 @@ var Chats = []map[string]string{ { "DeepChat": "deepchat://provider/install?v=1&data={deepchatConfig}", }, + { + "ETOS LLM Studio": "etosllmstudio://provider/install?v=1&data={etosConfig}", + }, { "Lobe Chat 官方示例": "https://chat-preview.lobehub.com/?settings={\"keyVaults\":{\"openai\":{\"apiKey\":\"{key}\",\"baseURL\":\"{address}/v1\"}}}", }, @@ -41,11 +40,11 @@ var Chats = []map[string]string{ func UpdateChatsByJsonString(jsonString string) error { Chats = make([]map[string]string, 0) - return json.Unmarshal([]byte(jsonString), &Chats) + return common.Unmarshal([]byte(jsonString), &Chats) } func Chats2JsonString() string { - jsonBytes, err := json.Marshal(Chats) + jsonBytes, err := common.Marshal(Chats) if err != nil { common.SysLog("error marshalling chats: " + err.Error()) return "[]" diff --git a/web/classic/src/components/layout/SiderBar.jsx b/web/classic/src/components/layout/SiderBar.jsx index a4375cf856cc..cf34347b32dd 100644 --- a/web/classic/src/components/layout/SiderBar.jsx +++ b/web/classic/src/components/layout/SiderBar.jsx @@ -254,7 +254,8 @@ const SiderBar = ({ onNavigate = () => {} }) => { if ( link.startsWith('fluent') || link.startsWith('ccswitch') || - link.startsWith('deepchat') + link.startsWith('deepchat') || + link.startsWith('etosllmstudio') ) { shouldSkip = true; break; diff --git a/web/classic/src/hooks/tokens/useTokensData.jsx b/web/classic/src/hooks/tokens/useTokensData.jsx index b26fd9fc781e..7f1307141821 100644 --- a/web/classic/src/hooks/tokens/useTokensData.jsx +++ b/web/classic/src/hooks/tokens/useTokensData.jsx @@ -261,6 +261,16 @@ export const useTokensData = (openFluentNotification, openCCSwitchModal) => { encodeToBase64(JSON.stringify(deepchatConfig)), ); url = url.replaceAll('{deepchatConfig}', encodedConfig); + } else if (url.includes('{etosConfig}') === true) { + let etosConfig = { + id: 'new-api', + baseUrl: serverAddress, + apiKey: `sk-${fullKey}`, + }; + let encodedConfig = encodeURIComponent( + encodeToBase64(JSON.stringify(etosConfig)), + ); + url = url.replaceAll('{etosConfig}', encodedConfig); } else { let encodedServerAddress = encodeURIComponent(serverAddress); url = url.replaceAll('{address}', encodedServerAddress); diff --git a/web/classic/src/pages/Setting/Chat/SettingsChats.jsx b/web/classic/src/pages/Setting/Chat/SettingsChats.jsx index fc1dae4cda68..8776833e5785 100644 --- a/web/classic/src/pages/Setting/Chat/SettingsChats.jsx +++ b/web/classic/src/pages/Setting/Chat/SettingsChats.jsx @@ -72,6 +72,7 @@ export default function SettingsChats(props) { { name: '流畅阅读', url: 'fluentread' }, { name: 'CC Switch', url: 'ccswitch' }, { name: 'DeepChat', url: 'deepchat://provider/install?v=1&data={deepchatConfig}' }, + { name: 'ETOS LLM Studio', url: 'etosllmstudio://provider/install?v=1&data={etosConfig}' }, { name: 'Lobe Chat', url: 'https://chat-preview.lobehub.com/?settings={"keyVaults":{"openai":{"apiKey":"{key}","baseURL":"{address}/v1"}}}' }, { name: 'AI as Workspace', url: 'https://aiaw.app/set-provider?provider={"type":"openai","settings":{"apiKey":"{key}","baseURL":"{address}/v1","compatibility":"strict"}}' }, { name: 'AMA 问天', url: 'ama://set-api-key?server={address}&key={key}' }, diff --git a/web/default/src/features/chat/lib/chat-links.ts b/web/default/src/features/chat/lib/chat-links.ts index 729a59fef4ef..de0c241f57a9 100644 --- a/web/default/src/features/chat/lib/chat-links.ts +++ b/web/default/src/features/chat/lib/chat-links.ts @@ -89,7 +89,8 @@ export function chatLinkRequiresApiKey(url: string): boolean { url.includes('{key}') || url.includes('{cherryConfig}') || url.includes('{aionuiConfig}') || - url.includes('{deepchatConfig}') + url.includes('{deepchatConfig}') || + url.includes('{etosConfig}') ) } @@ -189,6 +190,16 @@ export function resolveChatUrl({ return replaceToken(url, '{deepchatConfig}', encoded) } + if (url.includes('{etosConfig}')) { + const payload = { + id: 'new-api', + baseUrl: safeServerAddress, + apiKey: safeApiKey, + } + const encoded = encodeURIComponent(toBase64(JSON.stringify(payload))) + return replaceToken(url, '{etosConfig}', encoded) + } + if (safeServerAddress) { const encodedAddress = encodeURIComponent(safeServerAddress) url = replaceToken(url, '{address}', encodedAddress)