import type { LoggerFriendly, LoggerFriendlyOptions } from "#Source/log/index.ts" import { Logger } from "#Source/log/index.ts" import { Dispatcher } from "#Source/orchestration/index.ts" import { controllerFromEitherType, eitherToTuple } from "#Source/result/index.ts" import type { BaseEmbedding, EmbeddingOptions, EmbeddingResult } from "./embedding.ts" export interface EmbeddingAiOptions extends LoggerFriendlyOptions { embeddingInstanceList: BaseEmbedding[] /** * @description The maximum number of tries for the request. * * @default 3 */ maxTries?: number | undefined } interface ResolvedEmbeddingAiOptions { embeddingInstanceList: BaseEmbedding[] maxTries: number } export class EmbeddingAi implements LoggerFriendly { protected options: ResolvedEmbeddingAiOptions readonly logger: Logger private dispatcher: Dispatcher constructor(options: EmbeddingAiOptions) { this.options = { embeddingInstanceList: options.embeddingInstanceList, maxTries: options.maxTries ?? 3, } this.logger = Logger.fromOptions(options).setDefaultName("EmbeddingAi") this.dispatcher = new Dispatcher({ itemList: this.options.embeddingInstanceList, logger: this.logger.derive(), }) } async embedding(options: EmbeddingOptions): Promise { const controller = controllerFromEitherType() const { selector, destroy } = this.dispatcher.getSelector({ filter: (item) => { return item.isSupportModel(options.model) === true }, }) const [getItemLeft, getItemRight] = eitherToTuple(await selector.getItem()) if (getItemLeft !== undefined) { return await controller.returnLeft(getItemLeft) } const { item } = getItemRight // TODO: 实现重试逻辑 // const _maxTries = options.maxTries ?? this.options.maxTries const embeddingResult = await item.embedding(options) // 运行至此处,说明 embedding 成功,将 selector 销毁 destroy() return embeddingResult } }