Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"pdf-parse-new": "^1.3.9",
"pyodide": "^0.27.5",
"sharp": "^0.33.5",
"together-ai": "^0.16.0",
"tokenx": "^0.4.1",
"turndown": "^7.2.0",
"undici": "^7.8.0",
Expand Down
33 changes: 17 additions & 16 deletions src/main/presenter/configPresenter/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,21 +197,21 @@ export const DEFAULT_PROVIDERS: LLM_PROVIDER_BASE[] = [
// defaultBaseUrl: 'https://api.ocoolai.com'
// }
// },
// {
// id: 'together',
// name: 'Together',
// apiType: 'together',
// apiKey: '',
// baseUrl: 'https://api.tohgether.xyz',
// enable: false,
// websites: {
// official: 'https://www.together.ai/',
// apiKey: 'https://api.together.ai/settings/api-keys',
// docs: 'https://docs.together.ai/docs/introduction',
// models: 'https://docs.together.ai/docs/chat-models',
// defaultBaseUrl: 'https://api.tohgether.xyz'
// }
// },
{
id: 'together',
name: 'Together',
apiType: 'together',
apiKey: '',
baseUrl: 'https://api.together.xyz/v1',
enable: false,
websites: {
official: 'https://www.together.ai/',
apiKey: 'https://api.together.ai/settings/api-keys',
docs: 'https://docs.together.ai/docs/introduction',
models: 'https://docs.together.ai/docs/chat-models',
defaultBaseUrl: 'https://api.tohgether.xyz/v1'
}
},
{
id: 'github',
name: 'GitHub Models',
Expand All @@ -238,7 +238,8 @@ export const DEFAULT_PROVIDERS: LLM_PROVIDER_BASE[] = [
official: 'https://github.com/features/copilot',
apiKey: 'https://github.com/settings/tokens',
docs: 'https://docs.github.com/en/copilot',
models: 'https://docs.github.com/en/copilot/using-github-copilot/using-github-copilot-chat-in-your-ide',
models:
'https://docs.github.com/en/copilot/using-github-copilot/using-github-copilot-chat-in-your-ide',
defaultBaseUrl: 'https://api.githubcopilot.com'
}
},
Expand Down
4 changes: 2 additions & 2 deletions src/main/presenter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ ipcMain.handle(
return { error: `Method "${method}" not found or not a function on "${name}"` }
}
} catch (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
e: any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
e: any
) {
console.error('error on presenter handle', e) // 保留错误日志
return { error: e.message || String(e) }
Expand Down
3 changes: 3 additions & 0 deletions src/main/presenter/llmProviderPresenter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { AnthropicProvider } from './providers/anthropicProvider'
import { DoubaoProvider } from './providers/doubaoProvider'
import { ShowResponse } from 'ollama'
import { CONFIG_EVENTS } from '@/events'
import { TogetherProvider } from './providers/togetherProvider'
import { GrokProvider } from './providers/grokProvider'
import { presenter } from '@/presenter'
import { ZhipuProvider } from './providers/zhipuProvider'
Expand Down Expand Up @@ -126,6 +127,8 @@ export class LLMProviderPresenter implements ILlmProviderPresenter {
return new OpenAIResponsesProvider(provider, this.configPresenter)
case 'lmstudio':
return new LMStudioProvider(provider, this.configPresenter)
case 'together':
return new TogetherProvider(provider, this.configPresenter)
default:
console.warn(`Unknown provider type: ${provider.apiType}`)
return undefined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const SIZE_CONFIGURABLE_MODELS = ['gpt-image-1', 'gpt-4o-image', 'gpt-4o-all']

export class OpenAICompatibleProvider extends BaseLLMProvider {
protected openai!: OpenAI
private isNoModelsApi: boolean = false
protected isNoModelsApi: boolean = false
// 添加不支持 OpenAI 标准接口的供应商黑名单
private static readonly NO_MODELS_API_LIST: string[] = []

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { LLM_PROVIDER, LLMResponse, MODEL_META } from '@shared/presenter'
import { OpenAICompatibleProvider } from './openAICompatibleProvider'
import { ConfigPresenter } from '../../configPresenter'
import Together from 'together-ai'
export class TogetherProvider extends OpenAICompatibleProvider {
constructor(provider: LLM_PROVIDER, configPresenter: ConfigPresenter) {
super(provider, configPresenter)
}

async completions(
messages: { role: 'system' | 'user' | 'assistant'; content: string }[],
modelId: string,
temperature?: number,
maxTokens?: number
): Promise<LLMResponse> {
return this.openAICompletion(messages, modelId, temperature, maxTokens)
}

async summaries(
text: string,
modelId: string,
temperature?: number,
maxTokens?: number
): Promise<LLMResponse> {
return this.openAICompletion(
[
{
role: 'user',
content: `请总结以下内容,使用简洁的语言,突出重点:\n${text}`
}
],
modelId,
temperature,
maxTokens
)
}

async generateText(
prompt: string,
modelId: string,
temperature?: number,
maxTokens?: number
): Promise<LLMResponse> {
return this.openAICompletion(
[
{
role: 'user',
content: prompt
}
],
modelId,
temperature,
maxTokens
)
}
protected async fetchProviderModels(options?: { timeout: number }): Promise<MODEL_META[]> {
// 检查供应商是否在黑名单中
if (this.isNoModelsApi) {
// console.log(`Provider ${this.provider.name} does not support OpenAI models API`)
return this.models
}
return this.fetchTogetherAIModels(options)
}

protected async fetchTogetherAIModels(options?: { timeout: number }): Promise<MODEL_META[]> {
const togetherai = new Together({
apiKey: this.provider.apiKey
})
const response = await togetherai.models.list(options)
return response
.filter((model) => model.type === 'chat' || model.type === 'language')
.map((model) => ({
id: model.id,
name: model.id,
group: 'default',
providerId: this.provider.id,
isCustom: false,
contextLength: 4096,
maxTokens: 2048
}))
}
}