mirror of
https://github.com/logancyang/obsidian-copilot.git
synced 2026-07-22 07:50:24 +00:00
feat: Add SiliconFlow support for chat and embedding models (#1979)
This commit is contained in:
parent
42b078075c
commit
856ca91b29
5 changed files with 102 additions and 1 deletions
|
|
@ -52,6 +52,7 @@ const CHAT_PROVIDER_CONSTRUCTORS = {
|
|||
[ChatModelProviders.LM_STUDIO]: ChatOpenAI,
|
||||
[ChatModelProviders.GROQ]: ChatGroq,
|
||||
[ChatModelProviders.OPENAI_FORMAT]: ChatOpenAI,
|
||||
[ChatModelProviders.SILICONFLOW]: ChatOpenAI,
|
||||
[ChatModelProviders.COPILOT_PLUS]: ChatOpenAI,
|
||||
[ChatModelProviders.MISTRAL]: ChatMistralAI,
|
||||
[ChatModelProviders.DEEPSEEK]: ChatDeepSeek,
|
||||
|
|
@ -88,6 +89,7 @@ export default class ChatModelManager {
|
|||
[ChatModelProviders.MISTRAL]: () => getSettings().mistralApiKey,
|
||||
[ChatModelProviders.DEEPSEEK]: () => getSettings().deepseekApiKey,
|
||||
[ChatModelProviders.AMAZON_BEDROCK]: () => getSettings().amazonBedrockApiKey,
|
||||
[ChatModelProviders.SILICONFLOW]: () => getSettings().siliconflowApiKey,
|
||||
} as const;
|
||||
|
||||
private constructor() {
|
||||
|
|
@ -297,6 +299,20 @@ export default class ChatModelManager {
|
|||
customModel
|
||||
),
|
||||
},
|
||||
[ChatModelProviders.SILICONFLOW]: {
|
||||
modelName: modelName,
|
||||
apiKey: await getDecryptedKey(customModel.apiKey || settings.siliconflowApiKey),
|
||||
configuration: {
|
||||
baseURL: customModel.baseUrl || ProviderInfo[ChatModelProviders.SILICONFLOW].host,
|
||||
fetch: customModel.enableCors ? safeFetch : undefined,
|
||||
},
|
||||
...this.getOpenAISpecialConfig(
|
||||
modelName,
|
||||
customModel.maxTokens ?? settings.maxTokens,
|
||||
customModel.temperature ?? settings.temperature,
|
||||
customModel
|
||||
),
|
||||
},
|
||||
[ChatModelProviders.COPILOT_PLUS]: {
|
||||
modelName: modelName,
|
||||
apiKey: await getDecryptedKey(settings.plusLicenseKey),
|
||||
|
|
@ -477,6 +493,7 @@ export default class ChatModelManager {
|
|||
ChatModelProviders.OPENAI_FORMAT,
|
||||
ChatModelProviders.MISTRAL,
|
||||
ChatModelProviders.DEEPSEEK,
|
||||
ChatModelProviders.SILICONFLOW,
|
||||
].includes(provider)
|
||||
) {
|
||||
params.topP = customModel.topP;
|
||||
|
|
@ -496,6 +513,7 @@ export default class ChatModelManager {
|
|||
ChatModelProviders.OPENAI_FORMAT,
|
||||
ChatModelProviders.MISTRAL,
|
||||
ChatModelProviders.DEEPSEEK,
|
||||
ChatModelProviders.SILICONFLOW,
|
||||
].includes(provider)
|
||||
) {
|
||||
params.frequencyPenalty = customModel.frequencyPenalty;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { CustomModel } from "@/aiParams";
|
||||
import { BREVILABS_MODELS_BASE_URL, EmbeddingModelProviders } from "@/constants";
|
||||
import { BREVILABS_MODELS_BASE_URL, EmbeddingModelProviders, ProviderInfo } from "@/constants";
|
||||
import { getDecryptedKey } from "@/encryptionService";
|
||||
import { CustomError } from "@/error";
|
||||
import { getModelKeyFromModel, getSettings, subscribeToSettingsChange } from "@/settings/model";
|
||||
|
|
@ -27,6 +27,7 @@ const EMBEDDING_PROVIDER_CONSTRUCTORS = {
|
|||
[EmbeddingModelProviders.OLLAMA]: OllamaEmbeddings,
|
||||
[EmbeddingModelProviders.LM_STUDIO]: CustomOpenAIEmbeddings,
|
||||
[EmbeddingModelProviders.OPENAI_FORMAT]: OpenAIEmbeddings,
|
||||
[EmbeddingModelProviders.SILICONFLOW]: CustomOpenAIEmbeddings,
|
||||
} as const;
|
||||
|
||||
type EmbeddingProviderConstructorMap = typeof EMBEDDING_PROVIDER_CONSTRUCTORS;
|
||||
|
|
@ -54,6 +55,7 @@ export default class EmbeddingManager {
|
|||
[EmbeddingModelProviders.OLLAMA]: () => "default-key",
|
||||
[EmbeddingModelProviders.LM_STUDIO]: () => "default-key",
|
||||
[EmbeddingModelProviders.OPENAI_FORMAT]: () => "default-key",
|
||||
[EmbeddingModelProviders.SILICONFLOW]: () => getSettings().siliconflowApiKey,
|
||||
};
|
||||
|
||||
private constructor() {
|
||||
|
|
@ -279,6 +281,15 @@ export default class EmbeddingManager {
|
|||
dangerouslyAllowBrowser: true,
|
||||
},
|
||||
},
|
||||
[EmbeddingModelProviders.SILICONFLOW]: {
|
||||
modelName,
|
||||
apiKey: await getDecryptedKey(customModel.apiKey || settings.siliconflowApiKey),
|
||||
batchSize: getSettings().embeddingBatchSize,
|
||||
configuration: {
|
||||
baseURL: customModel.baseUrl || ProviderInfo[EmbeddingModelProviders.SILICONFLOW].host,
|
||||
fetch: customModel.enableCors ? safeFetch : undefined,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const selectedProviderConfig =
|
||||
|
|
|
|||
|
|
@ -166,6 +166,8 @@ export enum ChatModels {
|
|||
OPENROUTER_GPT_41 = "openai/gpt-4.1",
|
||||
OPENROUTER_GPT_41_MINI = "openai/gpt-4.1-mini",
|
||||
OPENROUTER_GROK_4_FAST = "x-ai/grok-4-fast",
|
||||
SILICONFLOW_DEEPSEEK_V3 = "deepseek-ai/DeepSeek-V3",
|
||||
SILICONFLOW_DEEPSEEK_R1 = "deepseek-ai/DeepSeek-R1",
|
||||
}
|
||||
|
||||
// Model Providers
|
||||
|
|
@ -185,6 +187,7 @@ export enum ChatModelProviders {
|
|||
MISTRAL = "mistralai",
|
||||
DEEPSEEK = "deepseek",
|
||||
AMAZON_BEDROCK = "amazon-bedrock",
|
||||
SILICONFLOW = "siliconflow",
|
||||
}
|
||||
|
||||
export enum ModelCapability {
|
||||
|
|
@ -381,6 +384,25 @@ export const BUILTIN_CHAT_MODELS: CustomModel[] = [
|
|||
isBuiltIn: true,
|
||||
capabilities: [ModelCapability.REASONING],
|
||||
},
|
||||
{
|
||||
name: ChatModels.SILICONFLOW_DEEPSEEK_V3,
|
||||
provider: ChatModelProviders.SILICONFLOW,
|
||||
enabled: true,
|
||||
isBuiltIn: true,
|
||||
core: true,
|
||||
projectEnabled: true,
|
||||
baseUrl: "https://api.siliconflow.com/v1",
|
||||
},
|
||||
{
|
||||
name: ChatModels.SILICONFLOW_DEEPSEEK_R1,
|
||||
provider: ChatModelProviders.SILICONFLOW,
|
||||
enabled: true,
|
||||
isBuiltIn: true,
|
||||
core: true,
|
||||
projectEnabled: true,
|
||||
baseUrl: "https://api.siliconflow.com/v1",
|
||||
capabilities: [ModelCapability.REASONING],
|
||||
},
|
||||
];
|
||||
|
||||
export enum EmbeddingModelProviders {
|
||||
|
|
@ -393,6 +415,7 @@ export enum EmbeddingModelProviders {
|
|||
OPENAI_FORMAT = "3rd party (openai-format)",
|
||||
COPILOT_PLUS = "copilot-plus",
|
||||
COPILOT_PLUS_JINA = "copilot-plus-jina",
|
||||
SILICONFLOW = "siliconflow",
|
||||
}
|
||||
|
||||
export enum EmbeddingModels {
|
||||
|
|
@ -406,6 +429,7 @@ export enum EmbeddingModels {
|
|||
COPILOT_PLUS_SMALL = "copilot-plus-small",
|
||||
COPILOT_PLUS_LARGE = "copilot-plus-large",
|
||||
COPILOT_PLUS_MULTILINGUAL = "copilot-plus-multilingual",
|
||||
SILICONFLOW_QWEN3_EMBEDDING_0_6B = "Qwen/Qwen3-Embedding-0.6B",
|
||||
}
|
||||
|
||||
export const BUILTIN_EMBEDDING_MODELS: CustomModel[] = [
|
||||
|
|
@ -483,6 +507,15 @@ export const BUILTIN_EMBEDDING_MODELS: CustomModel[] = [
|
|||
isBuiltIn: true,
|
||||
isEmbeddingModel: true,
|
||||
},
|
||||
{
|
||||
name: EmbeddingModels.SILICONFLOW_QWEN3_EMBEDDING_0_6B,
|
||||
provider: EmbeddingModelProviders.SILICONFLOW,
|
||||
enabled: true,
|
||||
isBuiltIn: true,
|
||||
isEmbeddingModel: true,
|
||||
core: true,
|
||||
baseUrl: "https://api.siliconflow.com/v1",
|
||||
},
|
||||
];
|
||||
|
||||
// Embedding Models
|
||||
|
|
@ -530,6 +563,13 @@ export const ProviderInfo: Record<Provider, ProviderMetadata> = {
|
|||
listModelURL: "https://api.openai.com/v1/models",
|
||||
testModel: ChatModels.GPT_41,
|
||||
},
|
||||
[ChatModelProviders.SILICONFLOW]: {
|
||||
label: "SiliconFlow",
|
||||
host: "https://api.siliconflow.com/v1",
|
||||
keyManagementURL: "https://cloud.siliconflow.com/me/account/ak",
|
||||
listModelURL: "https://api.siliconflow.com/v1/models",
|
||||
testModel: ChatModels.SILICONFLOW_DEEPSEEK_V3,
|
||||
},
|
||||
[ChatModelProviders.AZURE_OPENAI]: {
|
||||
label: "Azure OpenAI",
|
||||
host: "",
|
||||
|
|
@ -631,6 +671,7 @@ export const ProviderSettingsKeyMap: Record<SettingKeyProviders, keyof CopilotSe
|
|||
mistralai: "mistralApiKey",
|
||||
deepseek: "deepseekApiKey",
|
||||
"amazon-bedrock": "amazonBedrockApiKey",
|
||||
siliconflow: "siliconflowApiKey",
|
||||
};
|
||||
|
||||
export enum VAULT_VECTOR_STORE_STRATEGY {
|
||||
|
|
@ -749,6 +790,7 @@ export const DEFAULT_SETTINGS: CopilotSettings = {
|
|||
deepseekApiKey: "",
|
||||
amazonBedrockApiKey: "",
|
||||
amazonBedrockRegion: "",
|
||||
siliconflowApiKey: "",
|
||||
defaultChainType: ChainType.LLM_CHAIN,
|
||||
defaultModelKey: ChatModels.OPENROUTER_GEMINI_2_5_FLASH + "|" + ChatModelProviders.OPENROUTERAI,
|
||||
embeddingModelKey: EmbeddingModels.OPENAI_EMBEDDING_SMALL + "|" + EmbeddingModelProviders.OPENAI,
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ export interface CopilotSettings {
|
|||
deepseekApiKey: string;
|
||||
amazonBedrockApiKey: string;
|
||||
amazonBedrockRegion: string;
|
||||
siliconflowApiKey: string;
|
||||
defaultChainType: ChainType;
|
||||
defaultModelKey: string;
|
||||
embeddingModelKey: string;
|
||||
|
|
|
|||
|
|
@ -323,6 +323,27 @@ export interface OpenRouterAIModel {
|
|||
per_request_limits?: Record<string, string>;
|
||||
}
|
||||
|
||||
// SiliconFlow response model definition
|
||||
export interface SiliconFlowModelResponse {
|
||||
object: string;
|
||||
data: SiliconFlowModel[];
|
||||
}
|
||||
|
||||
/**
|
||||
{
|
||||
"id": "deepseek-ai/DeepSeek-V3",
|
||||
"object": "model",
|
||||
"created": 0,
|
||||
"owned_by": ""
|
||||
}
|
||||
*/
|
||||
export interface SiliconFlowModel {
|
||||
id: string;
|
||||
object: string;
|
||||
created: number;
|
||||
owned_by: string;
|
||||
}
|
||||
|
||||
// Response type mapping
|
||||
export interface ProviderResponseMap {
|
||||
[ChatModelProviders.OPENAI]: OpenAIModelResponse;
|
||||
|
|
@ -334,6 +355,7 @@ export interface ProviderResponseMap {
|
|||
[ChatModelProviders.GROQ]: GroqModelResponse;
|
||||
[ChatModelProviders.XAI]: XAIModelResponse;
|
||||
[ChatModelProviders.OPENROUTERAI]: OpenRouterAIModelResponse;
|
||||
[ChatModelProviders.SILICONFLOW]: SiliconFlowModelResponse;
|
||||
[ChatModelProviders.COPILOT_PLUS]: null;
|
||||
[ChatModelProviders.AZURE_OPENAI]: null;
|
||||
[ChatModelProviders.AMAZON_BEDROCK]: unknown;
|
||||
|
|
@ -421,6 +443,13 @@ export const providerAdapters: ProviderModelAdapters = {
|
|||
name: model.id,
|
||||
provider: ChatModelProviders.OPENROUTERAI,
|
||||
})) || [],
|
||||
|
||||
[ChatModelProviders.SILICONFLOW]: (data): StandardModel[] =>
|
||||
data.data?.map((model) => ({
|
||||
id: model.id,
|
||||
name: model.id,
|
||||
provider: ChatModelProviders.SILICONFLOW,
|
||||
})) || [],
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue