feat(providers): add transformers provider

This commit is contained in:
ItzCrazyKns
2025-10-19 18:32:18 +05:30
parent 51629b2cca
commit 65975ba6fc
5 changed files with 446 additions and 262 deletions

View File

@@ -13,6 +13,7 @@
"dependencies": { "dependencies": {
"@headlessui/react": "^2.2.0", "@headlessui/react": "^2.2.0",
"@headlessui/tailwindcss": "^0.2.2", "@headlessui/tailwindcss": "^0.2.2",
"@huggingface/transformers": "^3.7.5",
"@iarna/toml": "^2.2.5", "@iarna/toml": "^2.2.5",
"@icons-pack/react-simple-icons": "^12.3.0", "@icons-pack/react-simple-icons": "^12.3.0",
"@langchain/anthropic": "^0.3.24", "@langchain/anthropic": "^0.3.24",
@@ -24,7 +25,6 @@
"@langchain/openai": "^0.6.2", "@langchain/openai": "^0.6.2",
"@langchain/textsplitters": "^0.1.0", "@langchain/textsplitters": "^0.1.0",
"@tailwindcss/typography": "^0.5.12", "@tailwindcss/typography": "^0.5.12",
"@xenova/transformers": "^2.17.2",
"axios": "^1.8.3", "axios": "^1.8.3",
"better-sqlite3": "^11.9.1", "better-sqlite3": "^11.9.1",
"clsx": "^2.1.0", "clsx": "^2.1.0",

View File

@@ -1,5 +1,6 @@
import { Embeddings, type EmbeddingsParams } from '@langchain/core/embeddings'; import { Embeddings, type EmbeddingsParams } from '@langchain/core/embeddings';
import { chunkArray } from '@langchain/core/utils/chunk_array'; import { chunkArray } from '@langchain/core/utils/chunk_array';
import { pipeline } from '@huggingface/transformers';
export interface HuggingFaceTransformersEmbeddingsParams export interface HuggingFaceTransformersEmbeddingsParams
extends EmbeddingsParams { extends EmbeddingsParams {
@@ -67,12 +68,7 @@ export class HuggingFaceTransformersEmbeddings
} }
private async runEmbedding(texts: string[]) { private async runEmbedding(texts: string[]) {
const { pipeline } = await import('@xenova/transformers'); const pipe = await pipeline('feature-extraction', this.model);
const pipe = await (this.pipelinePromise ??= pipeline(
'feature-extraction',
this.model,
));
return this.caller.call(async () => { return this.caller.call(async () => {
const output = await pipe(texts, { pooling: 'mean', normalize: true }); const output = await pipe(texts, { pooling: 'mean', normalize: true });

View File

@@ -2,10 +2,12 @@ import { ModelProviderUISection } from '@/lib/config/types';
import { ProviderConstructor } from './baseProvider'; import { ProviderConstructor } from './baseProvider';
import OpenAIProvider from './openai'; import OpenAIProvider from './openai';
import OllamaProvider from './ollama'; import OllamaProvider from './ollama';
import TransformersProvider from './transformers';
export const providers: Record<string, ProviderConstructor<any>> = { export const providers: Record<string, ProviderConstructor<any>> = {
openai: OpenAIProvider, openai: OpenAIProvider,
ollama: OllamaProvider, ollama: OllamaProvider,
transformers: TransformersProvider,
}; };
export const getModelProvidersUIConfigSection = export const getModelProvidersUIConfigSection =

View File

@@ -0,0 +1,88 @@
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
import { Model, ModelList, ProviderMetadata } from '../types';
import BaseModelProvider from './baseProvider';
import { Embeddings } from '@langchain/core/embeddings';
import { UIConfigField } from '@/lib/config/types';
import { getConfiguredModelProviderById } from '@/lib/config/serverRegistry';
import { HuggingFaceTransformersEmbeddings } from '@/lib/huggingfaceTransformer';
interface TransformersConfig {}
const defaultEmbeddingModels: Model[] = [
{
name: 'all-MiniLM-L6-v2',
key: 'Xenova/all-MiniLM-L6-v2',
},
{
name: 'mxbai-embed-large-v1',
key: 'mixedbread-ai/mxbai-embed-large-v1',
},
{
name: 'nomic-embed-text-v1',
key: 'Xenova/nomic-embed-text-v1',
},
];
const providerConfigFields: UIConfigField[] = [];
class TransformersProvider extends BaseModelProvider<TransformersConfig> {
constructor(id: string, name: string, config: TransformersConfig) {
super(id, name, config);
}
async getDefaultModels(): Promise<ModelList> {
return {
embedding: [...defaultEmbeddingModels],
chat: [],
};
}
async getModelList(): Promise<ModelList> {
const defaultModels = await this.getDefaultModels();
const configProvider = getConfiguredModelProviderById(this.id)!;
return {
embedding: [
...defaultModels.embedding,
...configProvider.embeddingModels,
],
chat: [],
};
}
async loadChatModel(key: string): Promise<BaseChatModel> {
throw new Error('Transformers Provider does not support chat models.');
}
async loadEmbeddingModel(key: string): Promise<Embeddings> {
const modelList = await this.getModelList();
const exists = modelList.embedding.find((m) => m.key === key);
if (!exists) {
throw new Error(
'Error Loading OpenAI Embedding Model. Invalid Model Selected.',
);
}
return new HuggingFaceTransformersEmbeddings({
model: key,
});
}
static parseAndValidate(raw: any): TransformersConfig {
return {};
}
static getProviderConfigFields(): UIConfigField[] {
return providerConfigFields;
}
static getProviderMetadata(): ProviderMetadata {
return {
key: 'transformers',
name: 'Transformers',
};
}
}
export default TransformersProvider;

608
yarn.lock

File diff suppressed because it is too large Load Diff