fix: 加入账号轮询功能 #293
This commit is contained in:
parent
61ceca2363
commit
79cabadfb8
@ -289,6 +289,7 @@
|
||||
"advanced.title": "Advanced Settings",
|
||||
"advanced.click_assistant_switch_to_topics": "Auto switch to topic",
|
||||
"provider.api_key": "API Key",
|
||||
"provider.api_key.tip": "Multiple keys separated by commas",
|
||||
"provider.check": "Check",
|
||||
"provider.get_api_key": "Get API Key",
|
||||
"provider.api_host": "API Host",
|
||||
|
||||
@ -289,6 +289,7 @@
|
||||
"advanced.title": "高级设置",
|
||||
"advanced.click_assistant_switch_to_topics": "点击助手切换到话题",
|
||||
"provider.api_key": "API 密钥",
|
||||
"provider.api_key.tip": "多个密钥使用逗号分隔",
|
||||
"provider.check": "检查",
|
||||
"provider.get_api_key": "点击这里获取密钥",
|
||||
"provider.api_host": "API 地址",
|
||||
|
||||
@ -289,6 +289,7 @@
|
||||
"advanced.title": "進階設定",
|
||||
"advanced.click_assistant_switch_to_topics": "點擊助手切換到話題",
|
||||
"provider.api_key": "API 密鑰",
|
||||
"provider.api_key.tip": "多個密鑰使用逗號分隔",
|
||||
"provider.check": "檢查",
|
||||
"provider.get_api_key": "獲取 API 密鑰",
|
||||
"provider.api_host": "API 主機地址",
|
||||
|
||||
@ -118,7 +118,7 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
|
||||
<Input.Password
|
||||
value={apiKey}
|
||||
placeholder={t('settings.provider.api_key')}
|
||||
onChange={(e) => setApiKey(e.target.value)}
|
||||
onChange={(e) => setApiKey(e.target.value.replaceAll(',', ','))}
|
||||
onBlur={onUpdateApiKey}
|
||||
spellCheck={false}
|
||||
type="password"
|
||||
@ -129,10 +129,11 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
|
||||
</Button>
|
||||
</Space.Compact>
|
||||
{apiKeyWebsite && (
|
||||
<SettingHelpTextRow>
|
||||
<SettingHelpTextRow style={{ justifyContent: 'space-between' }}>
|
||||
<SettingHelpLink target="_blank" href={apiKeyWebsite}>
|
||||
{t('settings.provider.get_api_key')}
|
||||
</SettingHelpLink>
|
||||
<SettingHelpText>{t('settings.provider.api_key.tip')}</SettingHelpText>
|
||||
</SettingHelpTextRow>
|
||||
)}
|
||||
<SettingSubtitle>{t('settings.provider.api_host')}</SettingSubtitle>
|
||||
|
||||
@ -16,7 +16,7 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
|
||||
constructor(provider: Provider) {
|
||||
super(provider)
|
||||
this.sdk = new Anthropic({ apiKey: provider.apiKey, baseURL: this.getBaseURL() })
|
||||
this.sdk = new Anthropic({ apiKey: this.apiKey, baseURL: this.getBaseURL() })
|
||||
}
|
||||
|
||||
public getBaseURL(): string {
|
||||
|
||||
@ -6,10 +6,12 @@ import OpenAI from 'openai'
|
||||
export default abstract class BaseProvider {
|
||||
protected provider: Provider
|
||||
protected host: string
|
||||
protected apiKey: string
|
||||
|
||||
constructor(provider: Provider) {
|
||||
this.provider = provider
|
||||
this.host = this.getBaseURL()
|
||||
this.apiKey = this.getApiKey()
|
||||
}
|
||||
|
||||
public getBaseURL(): string {
|
||||
@ -17,9 +19,31 @@ export default abstract class BaseProvider {
|
||||
return host.endsWith('/') ? host : `${host}/v1/`
|
||||
}
|
||||
|
||||
public getApiKey() {
|
||||
const keys = this.provider.apiKey.split(',').map((key) => key.trim())
|
||||
const keyName = `provider:${this.provider.id}:last_used_key`
|
||||
|
||||
if (keys.length === 1) {
|
||||
return keys[0]
|
||||
}
|
||||
|
||||
const lastUsedKey = window.keyv.get(keyName)
|
||||
if (!lastUsedKey) {
|
||||
window.keyv.set(keyName, keys[0])
|
||||
return keys[0]
|
||||
}
|
||||
|
||||
const currentIndex = keys.indexOf(lastUsedKey)
|
||||
const nextIndex = (currentIndex + 1) % keys.length
|
||||
const nextKey = keys[nextIndex]
|
||||
window.keyv.set(keyName, nextKey)
|
||||
|
||||
return nextKey
|
||||
}
|
||||
|
||||
public defaultHeaders() {
|
||||
return {
|
||||
'X-Api-Key': this.provider.apiKey
|
||||
'X-Api-Key': this.apiKey
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ export default class GeminiProvider extends BaseProvider {
|
||||
|
||||
constructor(provider: Provider) {
|
||||
super(provider)
|
||||
this.sdk = new GoogleGenerativeAI(provider.apiKey)
|
||||
this.sdk = new GoogleGenerativeAI(this.apiKey)
|
||||
}
|
||||
|
||||
private async getMessageContents(message: Message): Promise<Content> {
|
||||
@ -231,7 +231,7 @@ export default class GeminiProvider extends BaseProvider {
|
||||
public async models(): Promise<OpenAI.Models.Model[]> {
|
||||
try {
|
||||
const api = this.provider.apiHost + '/v1beta/models'
|
||||
const { data } = await axios.get(api, { params: { key: this.provider.apiKey } })
|
||||
const { data } = await axios.get(api, { params: { key: this.apiKey } })
|
||||
return data.models.map(
|
||||
(m: any) =>
|
||||
({
|
||||
|
||||
@ -20,10 +20,11 @@ export default class OpenAIProvider extends BaseProvider {
|
||||
|
||||
constructor(provider: Provider) {
|
||||
super(provider)
|
||||
|
||||
if (provider.id === 'azure-openai') {
|
||||
this.sdk = new AzureOpenAI({
|
||||
dangerouslyAllowBrowser: true,
|
||||
apiKey: provider.apiKey,
|
||||
apiKey: this.apiKey,
|
||||
apiVersion: provider.apiVersion,
|
||||
endpoint: provider.apiHost
|
||||
})
|
||||
@ -32,7 +33,7 @@ export default class OpenAIProvider extends BaseProvider {
|
||||
|
||||
this.sdk = new OpenAI({
|
||||
dangerouslyAllowBrowser: true,
|
||||
apiKey: provider.apiKey,
|
||||
apiKey: this.apiKey,
|
||||
baseURL: this.getBaseURL(),
|
||||
defaultHeaders: this.defaultHeaders()
|
||||
})
|
||||
|
||||
@ -163,8 +163,6 @@ export async function fetchSuggestions({
|
||||
messages: Message[]
|
||||
assistant: Assistant
|
||||
}): Promise<Suggestion[]> {
|
||||
const provider = getAssistantProvider(assistant)
|
||||
const AI = new AiProvider(provider)
|
||||
const model = assistant.model
|
||||
|
||||
if (!model) {
|
||||
@ -179,6 +177,9 @@ export async function fetchSuggestions({
|
||||
return []
|
||||
}
|
||||
|
||||
const provider = getAssistantProvider(assistant)
|
||||
const AI = new AiProvider(provider)
|
||||
|
||||
try {
|
||||
return await AI.suggestions(filterMessages(messages), assistant)
|
||||
} catch (error: any) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user