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