{"version":3,"file":"embeddings.cjs","names":["Embeddings"],"sources":["../src/embeddings.ts"],"sourcesContent":["import type { Ai } from \"@cloudflare/workers-types\";\nimport { Embeddings, EmbeddingsParams } from \"@langchain/core/embeddings\";\nimport { chunkArray } from \"@langchain/core/utils/chunk_array\";\n\ntype AiTextEmbeddingsInput = {\n  text: string | string[];\n};\n\ntype AiTextEmbeddingsOutput = {\n  shape: number[];\n  data: number[][];\n};\n\nexport interface CloudflareWorkersAIEmbeddingsParams extends EmbeddingsParams {\n  /** Binding */\n  binding: Ai;\n\n  /**\n   * Model name to use\n   * Alias for `model`\n   */\n  modelName?: string;\n  /**\n   * Model name to use\n   */\n  model?: string;\n\n  /**\n   * The maximum number of documents to embed in a single request.\n   */\n  batchSize?: number;\n\n  /**\n   * Whether to strip new lines from the input text. This is recommended by\n   * OpenAI, but may not be suitable for all use cases.\n   */\n  stripNewLines?: boolean;\n}\n\nexport class CloudflareWorkersAIEmbeddings extends Embeddings {\n  modelName = \"@cf/baai/bge-base-en-v1.5\";\n\n  model = \"@cf/baai/bge-base-en-v1.5\";\n\n  batchSize = 50;\n\n  stripNewLines = true;\n\n  ai: Ai;\n\n  constructor(fields: CloudflareWorkersAIEmbeddingsParams) {\n    super(fields);\n\n    if (!fields.binding) {\n      throw new Error(\n        \"Must supply a Workers AI binding, eg { binding: env.AI }\"\n      );\n    }\n    this.ai = fields.binding;\n    this.modelName = fields?.model ?? fields.modelName ?? this.model;\n    this.model = this.modelName;\n    this.stripNewLines = fields.stripNewLines ?? this.stripNewLines;\n  }\n\n  async embedDocuments(texts: string[]): Promise<number[][]> {\n    const batches = chunkArray(\n      this.stripNewLines ? texts.map((t) => t.replace(/\\n/g, \" \")) : texts,\n      this.batchSize\n    );\n\n    const batchRequests = batches.map((batch) => this.runEmbedding(batch));\n    const batchResponses = await Promise.all(batchRequests);\n    const embeddings: number[][] = [];\n\n    for (let i = 0; i < batchResponses.length; i += 1) {\n      const batchResponse = batchResponses[i];\n      for (let j = 0; j < batchResponse.length; j += 1) {\n        embeddings.push(batchResponse[j]);\n      }\n    }\n\n    return embeddings;\n  }\n\n  async embedQuery(text: string): Promise<number[]> {\n    const data = await this.runEmbedding([\n      this.stripNewLines ? text.replace(/\\n/g, \" \") : text,\n    ]);\n    return data[0];\n  }\n\n  private async runEmbedding(texts: string[]) {\n    return this.caller.call(async () => {\n      const response: AiTextEmbeddingsOutput = await this.ai.run(\n        // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n        this.model as any,\n        {\n          text: texts,\n        } as AiTextEmbeddingsInput\n      );\n      return response.data;\n    });\n  }\n}\n"],"mappings":";;;;AAuCA,IAAa,gCAAb,cAAmDA,2BAAAA,WAAW;CAC5D,YAAY;CAEZ,QAAQ;CAER,YAAY;CAEZ,gBAAgB;CAEhB;CAEA,YAAY,QAA6C;AACvD,QAAM,OAAO;AAEb,MAAI,CAAC,OAAO,QACV,OAAM,IAAI,MACR,2DACD;AAEH,OAAK,KAAK,OAAO;AACjB,OAAK,YAAY,QAAQ,SAAS,OAAO,aAAa,KAAK;AAC3D,OAAK,QAAQ,KAAK;AAClB,OAAK,gBAAgB,OAAO,iBAAiB,KAAK;;CAGpD,MAAM,eAAe,OAAsC;EAMzD,MAAM,iBAAA,GAAA,kCAAA,YAJJ,KAAK,gBAAgB,MAAM,KAAK,MAAM,EAAE,QAAQ,OAAO,IAAI,CAAC,GAAG,OAC/D,KAAK,UAGsB,CAAC,KAAK,UAAU,KAAK,aAAa,MAAM,CAAC;EACtE,MAAM,iBAAiB,MAAM,QAAQ,IAAI,cAAc;EACvD,MAAM,aAAyB,EAAE;AAEjC,OAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK,GAAG;GACjD,MAAM,gBAAgB,eAAe;AACrC,QAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK,EAC7C,YAAW,KAAK,cAAc,GAAG;;AAIrC,SAAO;;CAGT,MAAM,WAAW,MAAiC;AAIhD,UAAO,MAHY,KAAK,aAAa,CACnC,KAAK,gBAAgB,KAAK,QAAQ,OAAO,IAAI,GAAG,KACjD,CAAC,EACU;;CAGd,MAAc,aAAa,OAAiB;AAC1C,SAAO,KAAK,OAAO,KAAK,YAAY;AAQlC,WAAO,MAPwC,KAAK,GAAG,IAErD,KAAK,OACL,EACE,MAAM,OACP,CACF,EACe;IAChB"}