{"version":3,"file":"voyage.cjs","names":["Embeddings"],"sources":["../../src/embeddings/voyage.ts"],"sourcesContent":["import { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { Embeddings, type EmbeddingsParams } from \"@langchain/core/embeddings\";\nimport { chunkArray } from \"@langchain/core/utils/chunk_array\";\n\n/**\n * Interface that extends EmbeddingsParams and defines additional\n * parameters specific to the VoyageEmbeddings class.\n */\nexport interface VoyageEmbeddingsParams extends EmbeddingsParams {\n  modelName: string;\n\n  /**\n   * Base URL for Voyage API requests.\n   * If your API key was created on the MongoDB Atlas UI, it should look like `'https://ai.mongodb.com/v1'`.\n   * If your API key was created on the Voyage AI Dashboard, it should look like `'https://api.voyageai.com/v1'`.\n   * @default \"https://api.voyageai.com/v1\"\n   * @see https://www.mongodb.com/docs/voyageai/management/api-keys/?client-curl-default=curl#create-an-api-key\n   */\n  basePath?: string;\n\n  /**\n   * The maximum number of documents to embed in a single request. This is\n   * limited by the Voyage AI API to a maximum of 8.\n   */\n  batchSize?: number;\n\n  /**\n   * Input type for the embeddings request.\n   */\n  inputType?: string;\n\n  /**\n   * Whether to truncate the input texts to the maximum length allowed by the model.\n   */\n  truncation?: boolean;\n\n  /**\n   * The desired dimension of the output embeddings.\n   */\n  outputDimension?: number;\n\n  /**\n   * The data type of the output embeddings. Can be \"float\" or \"int8\".\n   */\n  outputDtype?: string;\n\n  /**\n   * The format of the output embeddings. Can be \"float\", \"base64\", or \"ubinary\".\n   */\n  encodingFormat?: string;\n}\n\n/**\n * Interface for the request body to generate embeddings.\n */\nexport interface CreateVoyageEmbeddingRequest {\n  /**\n   * @type {string}\n   * @memberof CreateVoyageEmbeddingRequest\n   */\n  model: string;\n\n  /**\n   *  Text to generate vector expectation\n   * @type {CreateEmbeddingRequestInput}\n   * @memberof CreateVoyageEmbeddingRequest\n   */\n  input: string | string[];\n\n  /**\n   * Input type for the embeddings request.\n   */\n  input_type?: string;\n\n  /**\n   * Whether to truncate the input texts.\n   */\n  truncation?: boolean;\n\n  /**\n   * The desired dimension of the output embeddings.\n   */\n  output_dimension?: number;\n\n  /**\n   * The data type of the output embeddings.\n   */\n  output_dtype?: string;\n\n  /**\n   * The format of the output embeddings.\n   */\n  encoding_format?: string;\n}\n\n/**\n * The shape of a successful response from the Voyage AI embeddings endpoint.\n * @see https://docs.voyageai.com/reference/embeddings-api\n */\ninterface VoyageEmbeddingResponse {\n  object: \"list\";\n  data: Array<{ object: \"embedding\"; embedding: number[]; index: number }>;\n  model: string;\n  usage: { total_tokens: number };\n}\n\nfunction extractErrorMessage(body: unknown): string {\n  if (typeof body === \"object\" && body !== null) {\n    const b = body as Record<string, unknown>;\n    if (typeof b.detail === \"string\") return b.detail;\n    const err = b.error;\n    if (\n      typeof err === \"object\" &&\n      err !== null &&\n      typeof (err as Record<string, unknown>).message === \"string\"\n    ) {\n      return (err as Record<string, unknown>).message as string;\n    }\n    return JSON.stringify(body);\n  }\n  return `Unknown error: ${String(body)}`;\n}\n\n/**\n * A class for generating embeddings using the Voyage AI API.\n */\nexport class VoyageEmbeddings\n  extends Embeddings\n  implements VoyageEmbeddingsParams\n{\n  modelName = \"voyage-01\";\n\n  batchSize = 8;\n\n  private apiKey: string;\n\n  /** Do not modify directly. Pass in the basePath option to the constructor. */\n  basePath?: string = \"https://api.voyageai.com/v1\";\n\n  apiUrl: string;\n\n  headers?: Record<string, string>;\n\n  inputType?: string;\n\n  truncation?: boolean;\n\n  outputDimension?: number;\n\n  outputDtype?: string;\n\n  encodingFormat?: string;\n\n  /**\n   * Constructor for the VoyageEmbeddings class.\n   * @param fields - An optional object with properties to configure the instance.\n   */\n  constructor(\n    fields?: Partial<VoyageEmbeddingsParams> & {\n      verbose?: boolean;\n      apiKey?: string;\n      inputType?: string;\n      basePath?: string;\n    }\n  ) {\n    const fieldsWithDefaults = { ...fields };\n\n    super(fieldsWithDefaults);\n\n    const apiKey =\n      fieldsWithDefaults?.apiKey || getEnvironmentVariable(\"VOYAGEAI_API_KEY\");\n\n    if (!apiKey) {\n      throw new Error(\"Voyage AI API key not found\");\n    }\n\n    this.modelName = fieldsWithDefaults?.modelName ?? this.modelName;\n    this.batchSize = fieldsWithDefaults?.batchSize ?? this.batchSize;\n    this.apiKey = apiKey;\n    this.basePath = fieldsWithDefaults?.basePath ?? this.basePath;\n    this.apiUrl = `${this.basePath}/embeddings`;\n    this.inputType = fieldsWithDefaults?.inputType;\n    this.truncation = fieldsWithDefaults?.truncation;\n    this.outputDimension = fieldsWithDefaults?.outputDimension;\n    this.outputDtype = fieldsWithDefaults?.outputDtype;\n    this.encodingFormat = fieldsWithDefaults?.encodingFormat;\n  }\n\n  /**\n   * Generates embeddings for an array of texts.\n   * @param texts - An array of strings to generate embeddings for.\n   * @returns A Promise that resolves to an array of embeddings.\n   */\n  async embedDocuments(texts: string[]): Promise<number[][]> {\n    const batches = chunkArray(texts, this.batchSize);\n\n    const batchRequests = batches.map((batch) =>\n      this.embeddingWithRetry({\n        model: this.modelName,\n        input: batch,\n        input_type: this.inputType,\n        truncation: this.truncation,\n        output_dimension: this.outputDimension,\n        output_dtype: this.outputDtype,\n        encoding_format: this.encodingFormat,\n      })\n    );\n\n    const batchResponses = await Promise.all(batchRequests);\n\n    const embeddings: number[][] = [];\n\n    for (let i = 0; i < batchResponses.length; i += 1) {\n      const batch = batches[i];\n      const { data: batchResponse } = batchResponses[i];\n      for (let j = 0; j < batch.length; j += 1) {\n        embeddings.push(batchResponse[j].embedding);\n      }\n    }\n\n    return embeddings;\n  }\n\n  /**\n   * Generates an embedding for a single text.\n   * @param text - A string to generate an embedding for.\n   * @returns A Promise that resolves to an array of numbers representing the embedding.\n   */\n  async embedQuery(text: string): Promise<number[]> {\n    const { data } = await this.embeddingWithRetry({\n      model: this.modelName,\n      input: text,\n      input_type: this.inputType,\n      truncation: this.truncation,\n      output_dimension: this.outputDimension,\n      output_dtype: this.outputDtype,\n      encoding_format: this.encodingFormat,\n    });\n\n    return data[0].embedding;\n  }\n\n  /**\n   * Makes a request to the Voyage AI API to generate embeddings for an array of texts.\n   * @param request - An object with properties to configure the request.\n   * @returns A Promise that resolves to the response from the Voyage AI API.\n   */\n  private async embeddingWithRetry(\n    request: CreateVoyageEmbeddingRequest\n  ): Promise<VoyageEmbeddingResponse> {\n    const makeCompletionRequest = async () => {\n      const url = `${this.apiUrl}`;\n      const response = await fetch(url, {\n        method: \"POST\",\n        headers: {\n          \"Content-Type\": \"application/json\",\n          Authorization: `Bearer ${this.apiKey}`,\n          ...this.headers,\n        },\n        body: JSON.stringify(request),\n      });\n\n      let json: unknown;\n      try {\n        json = await response.json();\n      } catch (error) {\n        console.error(\"Failed to parse JSON response:\", error);\n        json = null;\n      }\n\n      if (!response.ok) {\n        const message = extractErrorMessage(json);\n        const err = new Error(\n          `Voyage AI API error (HTTP ${response.status}): ${message}`\n        );\n        // Attach status so AsyncCaller's defaultFailedAttemptHandler can\n        // skip retries for non-transient HTTP errors (4xx).\n        (err as NodeJS.ErrnoException & { status: number }).status =\n          response.status;\n        throw err;\n      }\n\n      return json as VoyageEmbeddingResponse;\n    };\n\n    return this.caller.call(makeCompletionRequest);\n  }\n}\n"],"mappings":"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"}