{"version":3,"file":"media_core.cjs","names":["Serializable","BaseStore"],"sources":["../../../src/experimental/utils/media_core.ts"],"sourcesContent":["import { v1, v4 } from \"@langchain/core/utils/uuid\"; // FIXME - it is importing the wrong uuid, so v6 and v7 aren't implemented\nimport { BaseStore } from \"@langchain/core/stores\";\nimport { Serializable } from \"@langchain/core/load/serializable\";\n\nexport type MediaBlobData = {\n  value: string; // In Base64 encoding\n  type: string; // The mime type and possibly encoding\n};\n\nexport interface MediaBlobParameters {\n  data?: MediaBlobData;\n\n  metadata?: Record<string, unknown>;\n\n  path?: string;\n}\n\nfunction bytesToString(dataArray: Uint8Array): string {\n  // Need to handle the array in smaller chunks to deal with stack size limits\n  let ret = \"\";\n  const chunkSize = 102400;\n  for (let i = 0; i < dataArray.length; i += chunkSize) {\n    const chunk = dataArray.subarray(i, i + chunkSize);\n    ret += String.fromCharCode(...chunk);\n  }\n\n  return ret;\n}\n\n/**\n * Represents a chunk of data that can be identified by the path where the\n * data is (or will be) located, along with optional metadata about the data.\n */\nexport class MediaBlob extends Serializable implements MediaBlobParameters {\n  lc_serializable = true;\n\n  lc_namespace = [\n    \"langchain\",\n    \"google_common\",\n    \"experimental\",\n    \"utils\",\n    \"media_core\",\n  ];\n\n  data: MediaBlobData = {\n    value: \"\",\n    type: \"text/plain\",\n  };\n\n  // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n  metadata?: Record<string, any>;\n\n  path?: string;\n\n  constructor(params: MediaBlobParameters) {\n    super(params);\n\n    this.data = params.data ?? this.data;\n    this.metadata = params.metadata;\n    this.path = params.path;\n  }\n\n  get size(): number {\n    return this.asBytes.length;\n  }\n\n  get dataType(): string {\n    return this.data?.type ?? \"\";\n  }\n\n  get encoding(): string {\n    const charsetEquals = this.dataType.indexOf(\"charset=\");\n    return charsetEquals === -1\n      ? \"utf-8\"\n      : this.dataType.substring(charsetEquals + 8);\n  }\n\n  get mimetype(): string {\n    const semicolon = this.dataType.indexOf(\";\");\n    return semicolon === -1\n      ? this.dataType\n      : this.dataType.substring(0, semicolon);\n  }\n\n  get asBytes(): Uint8Array {\n    if (!this.data) {\n      return Uint8Array.from([]);\n    }\n    const binString = atob(this.data?.value);\n    const ret = new Uint8Array(binString.length);\n    for (let co = 0; co < binString.length; co += 1) {\n      ret[co] = binString.charCodeAt(co);\n    }\n    return ret;\n  }\n\n  async asString(): Promise<string> {\n    return bytesToString(this.asBytes);\n  }\n\n  async asBase64(): Promise<string> {\n    return this.data?.value ?? \"\";\n  }\n\n  async asDataUrl(): Promise<string> {\n    return `data:${this.mimetype};base64,${await this.asBase64()}`;\n  }\n\n  async asUri(): Promise<string> {\n    return this.path ?? (await this.asDataUrl());\n  }\n\n  async encode(): Promise<{ encoded: string; encoding: string }> {\n    const dataUrl = await this.asDataUrl();\n    const comma = dataUrl.indexOf(\",\");\n    const encoded = dataUrl.substring(comma + 1);\n    const encoding: string = dataUrl.indexOf(\"base64\") > -1 ? \"base64\" : \"8bit\";\n    return {\n      encoded,\n      encoding,\n    };\n  }\n\n  static fromDataUrl(url: string): MediaBlob {\n    if (!url.startsWith(\"data:\")) {\n      throw new Error(\"Not a data: URL\");\n    }\n    const colon = url.indexOf(\":\");\n    const semicolon = url.indexOf(\";\");\n    const mimeType = url.substring(colon + 1, semicolon);\n\n    const comma = url.indexOf(\",\");\n    const base64Data = url.substring(comma + 1);\n\n    const data: MediaBlobData = {\n      type: mimeType,\n      value: base64Data,\n    };\n\n    return new MediaBlob({\n      data,\n      path: url,\n    });\n  }\n\n  static async fromBlob(\n    blob: Blob,\n    other?: Omit<MediaBlobParameters, \"data\">\n  ): Promise<MediaBlob> {\n    const valueBuffer = await blob.arrayBuffer();\n    const valueArray = new Uint8Array(valueBuffer);\n    const valueStr = bytesToString(valueArray);\n    const value = btoa(valueStr);\n\n    return new MediaBlob({\n      ...other,\n      data: {\n        value,\n        type: blob.type,\n      },\n    });\n  }\n}\n\nexport type ActionIfInvalidAction =\n  | \"ignore\"\n  | \"prefixPath\"\n  | \"prefixUuid1\"\n  | \"prefixUuid4\"\n  | \"prefixUuid6\"\n  | \"prefixUuid7\"\n  | \"removePath\";\n\nexport interface BlobStoreStoreOptions {\n  /**\n   * If the path is missing or invalid in the blob, how should we create\n   * a new path?\n   * Subclasses may define their own methods, but the following are supported\n   * by default:\n   * - Undefined or an emtpy string: Reject the blob\n   * - \"ignore\": Attempt to store it anyway (but this may fail)\n   * - \"prefixPath\": Use the default prefix for the BlobStore and get the\n   *   unique portion from the URL. The original path is stored in the metadata\n   * - \"prefixUuid\": Use the default prefix for the BlobStore and get the\n   *   unique portion from a generated UUID. The original path is stored\n   *   in the metadata\n   */\n  actionIfInvalid?: ActionIfInvalidAction;\n\n  /**\n   * The expected prefix for URIs that are stored.\n   * This may be used to test if a MediaBlob is valid and used to create a new\n   * path if \"prefixPath\" or \"prefixUuid\" is set for actionIfInvalid.\n   */\n  pathPrefix?: string;\n}\n\nexport type ActionIfBlobMissingAction = \"emptyBlob\";\n\nexport interface BlobStoreFetchOptions {\n  /**\n   * If the blob is not found when fetching, what should we do?\n   * Subclasses may define their own methods, but the following are supported\n   * by default:\n   * - Undefined or an empty string: return undefined\n   * - \"emptyBlob\": return a new MediaBlob that has the path set, but nothing else.\n   */\n  actionIfBlobMissing?: ActionIfBlobMissingAction;\n}\n\nexport interface BlobStoreOptions {\n  defaultStoreOptions?: BlobStoreStoreOptions;\n\n  defaultFetchOptions?: BlobStoreFetchOptions;\n}\n\n/**\n * A specialized Store that is designed to handle MediaBlobs and use the\n * key that is included in the blob to determine exactly how it is stored.\n *\n * The full details of a MediaBlob may be changed when it is stored.\n * For example, it may get additional or different Metadata. This should be\n * what is returned when the store() method is called.\n *\n * Although BlobStore extends BaseStore, not all of the methods from\n * BaseStore may be implemented (or even possible). Those that are not\n * implemented should be documented and throw an Error if called.\n */\nexport abstract class BlobStore extends BaseStore<string, MediaBlob> {\n  lc_namespace = [\"langchain\", \"google-common\"]; // FIXME - What should this be? And why?\n\n  defaultStoreOptions: BlobStoreStoreOptions;\n\n  defaultFetchOptions: BlobStoreFetchOptions;\n\n  constructor(opts?: BlobStoreOptions) {\n    super(opts);\n    this.defaultStoreOptions = opts?.defaultStoreOptions ?? {};\n    this.defaultFetchOptions = opts?.defaultFetchOptions ?? {};\n  }\n\n  protected async _realKey(key: string | MediaBlob): Promise<string> {\n    return typeof key === \"string\" ? key : await key.asUri();\n  }\n\n  /**\n   * Is the path supported by this BlobStore?\n   *\n   * Although this is async, this is expected to be a relatively fast operation\n   * (ie - you shouldn't make network calls).\n   *\n   * @param path The path to check\n   * @param opts Any options (if needed) that may be used to determine if it is valid\n   * @return If the path is supported\n   */\n  hasValidPath(\n    path: string | undefined,\n    opts?: BlobStoreStoreOptions\n  ): Promise<boolean> {\n    const prefix = opts?.pathPrefix ?? \"\";\n    const isPrefixed = typeof path !== \"undefined\" && path.startsWith(prefix);\n    return Promise.resolve(isPrefixed);\n  }\n\n  protected _blobPathSuffix(blob: MediaBlob): string {\n    // Get the path currently set and make sure we treat it as a string\n    const blobPath = `${blob.path}`;\n\n    // Advance past the first set of /\n    let pathStart = blobPath.indexOf(\"/\") + 1;\n    while (blobPath.charAt(pathStart) === \"/\") {\n      pathStart += 1;\n    }\n\n    // We will use the rest as the path for a replacement\n    return blobPath.substring(pathStart);\n  }\n\n  protected async _newBlob(\n    oldBlob: MediaBlob,\n    newPath?: string\n  ): Promise<MediaBlob> {\n    const oldPath = oldBlob.path;\n    const metadata = oldBlob?.metadata ?? {};\n    metadata.langchainOldPath = oldPath;\n    const newBlob = new MediaBlob({\n      ...oldBlob,\n      metadata,\n    });\n    if (newPath) {\n      newBlob.path = newPath;\n    } else if (newBlob.path) {\n      delete newBlob.path;\n    }\n    return newBlob;\n  }\n\n  protected async _validBlobPrefixPath(\n    blob: MediaBlob,\n    opts?: BlobStoreStoreOptions\n  ): Promise<MediaBlob> {\n    const prefix = opts?.pathPrefix ?? \"\";\n    const suffix = this._blobPathSuffix(blob);\n    const newPath = `${prefix}${suffix}`;\n    return this._newBlob(blob, newPath);\n  }\n\n  protected _validBlobPrefixUuidFunction(\n    name: ActionIfInvalidAction | string\n  ): string {\n    switch (name) {\n      case \"prefixUuid1\":\n        return v1();\n      case \"prefixUuid4\":\n        return v4();\n      // case \"prefixUuid6\": return v6();\n      // case \"prefixUuid7\": return v7();\n      default:\n        throw new Error(`Unknown uuid function: ${name}`);\n    }\n  }\n\n  protected async _validBlobPrefixUuid(\n    blob: MediaBlob,\n    opts?: BlobStoreStoreOptions\n  ): Promise<MediaBlob> {\n    const prefix = opts?.pathPrefix ?? \"\";\n    const suffix = this._validBlobPrefixUuidFunction(\n      opts?.actionIfInvalid ?? \"prefixUuid4\"\n    );\n    const newPath = `${prefix}${suffix}`;\n    return this._newBlob(blob, newPath);\n  }\n\n  protected async _validBlobRemovePath(\n    blob: MediaBlob,\n    _opts?: BlobStoreStoreOptions\n  ): Promise<MediaBlob> {\n    return this._newBlob(blob, undefined);\n  }\n\n  /**\n   * Based on the blob and options, return a blob that has a valid path\n   * that can be saved.\n   * @param blob\n   * @param opts\n   */\n  protected async _validStoreBlob(\n    blob: MediaBlob,\n    opts?: BlobStoreStoreOptions\n  ): Promise<MediaBlob | undefined> {\n    if (await this.hasValidPath(blob.path, opts)) {\n      return blob;\n    }\n    switch (opts?.actionIfInvalid) {\n      case \"ignore\":\n        return blob;\n      case \"prefixPath\":\n        return this._validBlobPrefixPath(blob, opts);\n      case \"prefixUuid1\":\n      case \"prefixUuid4\":\n      case \"prefixUuid6\":\n      case \"prefixUuid7\":\n        return this._validBlobPrefixUuid(blob, opts);\n      case \"removePath\":\n        return this._validBlobRemovePath(blob, opts);\n      default:\n        return undefined;\n    }\n  }\n\n  async store(\n    blob: MediaBlob,\n    opts: BlobStoreStoreOptions = {}\n  ): Promise<MediaBlob | undefined> {\n    const allOpts: BlobStoreStoreOptions = {\n      ...this.defaultStoreOptions,\n      ...opts,\n    };\n    const validBlob = await this._validStoreBlob(blob, allOpts);\n    if (typeof validBlob !== \"undefined\") {\n      const validKey = await validBlob.asUri();\n      await this.mset([[validKey, validBlob]]);\n      const savedKey = await validBlob.asUri();\n      return await this.fetch(savedKey);\n    }\n    return undefined;\n  }\n\n  protected async _missingFetchBlobEmpty(\n    path: string,\n    _opts?: BlobStoreFetchOptions\n  ): Promise<MediaBlob> {\n    return new MediaBlob({ path });\n  }\n\n  protected async _missingFetchBlob(\n    path: string,\n    opts?: BlobStoreFetchOptions\n  ): Promise<MediaBlob | undefined> {\n    switch (opts?.actionIfBlobMissing) {\n      case \"emptyBlob\":\n        return this._missingFetchBlobEmpty(path, opts);\n      default:\n        return undefined;\n    }\n  }\n\n  async fetch(\n    key: string | MediaBlob,\n    opts: BlobStoreFetchOptions = {}\n  ): Promise<MediaBlob | undefined> {\n    const allOpts: BlobStoreFetchOptions = {\n      ...this.defaultFetchOptions,\n      ...opts,\n    };\n    const realKey = await this._realKey(key);\n    const ret = await this.mget([realKey]);\n    return ret?.[0] ?? (await this._missingFetchBlob(realKey, allOpts));\n  }\n}\n\nexport interface BackedBlobStoreOptions extends BlobStoreOptions {\n  backingStore: BaseStore<string, MediaBlob>;\n}\n\nexport class BackedBlobStore extends BlobStore {\n  backingStore: BaseStore<string, MediaBlob>;\n\n  constructor(opts: BackedBlobStoreOptions) {\n    super(opts);\n    this.backingStore = opts.backingStore;\n  }\n\n  mdelete(keys: string[]): Promise<void> {\n    return this.backingStore.mdelete(keys);\n  }\n\n  mget(keys: string[]): Promise<(MediaBlob | undefined)[]> {\n    return this.backingStore.mget(keys);\n  }\n\n  mset(keyValuePairs: [string, MediaBlob][]): Promise<void> {\n    return this.backingStore.mset(keyValuePairs);\n  }\n\n  yieldKeys(prefix: string | undefined): AsyncGenerator<string> {\n    return this.backingStore.yieldKeys(prefix);\n  }\n}\n\nexport interface ReadThroughBlobStoreOptions extends BlobStoreOptions {\n  baseStore: BlobStore;\n  backingStore: BlobStore;\n}\n\nexport class ReadThroughBlobStore extends BlobStore {\n  baseStore: BlobStore;\n\n  backingStore: BlobStore;\n\n  constructor(opts: ReadThroughBlobStoreOptions) {\n    super(opts);\n    this.baseStore = opts.baseStore;\n    this.backingStore = opts.backingStore;\n  }\n\n  async store(\n    blob: MediaBlob,\n    opts: BlobStoreStoreOptions = {}\n  ): Promise<MediaBlob | undefined> {\n    const originalUri = await blob.asUri();\n    const newBlob = await this.backingStore.store(blob, opts);\n    if (newBlob) {\n      await this.baseStore.mset([[originalUri, newBlob]]);\n    }\n    return newBlob;\n  }\n\n  mdelete(keys: string[]): Promise<void> {\n    return this.baseStore.mdelete(keys);\n  }\n\n  mget(keys: string[]): Promise<(MediaBlob | undefined)[]> {\n    return this.baseStore.mget(keys);\n  }\n\n  mset(_keyValuePairs: [string, MediaBlob][]): Promise<void> {\n    throw new Error(\"Do not call ReadThroughBlobStore.mset directly\");\n  }\n\n  yieldKeys(prefix: string | undefined): AsyncGenerator<string> {\n    return this.baseStore.yieldKeys(prefix);\n  }\n}\n\nexport class SimpleWebBlobStore extends BlobStore {\n  _notImplementedException() {\n    throw new Error(\"Not implemented for SimpleWebBlobStore\");\n  }\n\n  async hasValidPath(\n    path: string | undefined,\n    _opts?: BlobStoreStoreOptions\n  ): Promise<boolean> {\n    return (\n      (await super.hasValidPath(path, { pathPrefix: \"https://\" })) ||\n      (await super.hasValidPath(path, { pathPrefix: \"http://\" }))\n    );\n  }\n\n  async _fetch(url: string): Promise<MediaBlob | undefined> {\n    const ret = new MediaBlob({\n      path: url,\n    });\n    const metadata: Record<string, unknown> = {};\n    const fetchOptions = {\n      method: \"GET\",\n    };\n    const res = await fetch(url, fetchOptions);\n    metadata.status = res.status;\n\n    const headers: Record<string, string> = {};\n    for (const [key, value] of res.headers.entries()) {\n      headers[key] = value;\n    }\n    metadata.headers = headers;\n\n    metadata.ok = res.ok;\n    if (res.ok) {\n      const resMediaBlob = await MediaBlob.fromBlob(await res.blob());\n      ret.data = resMediaBlob.data;\n    }\n\n    ret.metadata = metadata;\n    return ret;\n  }\n\n  async mget(keys: string[]): Promise<(MediaBlob | undefined)[]> {\n    const blobMap = keys.map(this._fetch);\n    return await Promise.all(blobMap);\n  }\n\n  async mdelete(_keys: string[]): Promise<void> {\n    this._notImplementedException();\n  }\n\n  async mset(_keyValuePairs: [string, MediaBlob][]): Promise<void> {\n    this._notImplementedException();\n  }\n\n  async *yieldKeys(_prefix: string | undefined): AsyncGenerator<string> {\n    this._notImplementedException();\n    yield \"\";\n  }\n}\n\n/**\n * A blob \"store\" that works with data: URLs that will turn the URL into\n * a blob.\n */\nexport class DataBlobStore extends BlobStore {\n  _notImplementedException() {\n    throw new Error(\"Not implemented for DataBlobStore\");\n  }\n\n  hasValidPath(path: string, _opts?: BlobStoreStoreOptions): Promise<boolean> {\n    return super.hasValidPath(path, { pathPrefix: \"data:\" });\n  }\n\n  _fetch(url: string): MediaBlob {\n    return MediaBlob.fromDataUrl(url);\n  }\n\n  async mget(keys: string[]): Promise<(MediaBlob | undefined)[]> {\n    const blobMap = keys.map(this._fetch);\n    return blobMap;\n  }\n\n  async mdelete(_keys: string[]): Promise<void> {\n    this._notImplementedException();\n  }\n\n  async mset(_keyValuePairs: [string, MediaBlob][]): Promise<void> {\n    this._notImplementedException();\n  }\n\n  async *yieldKeys(_prefix: string | undefined): AsyncGenerator<string> {\n    this._notImplementedException();\n    yield \"\";\n  }\n}\n\nexport interface MediaManagerConfiguration {\n  /**\n   * A store that, given a common URI, returns the corresponding MediaBlob.\n   * The returned MediaBlob may have a different URI.\n   * In many cases, this will be a ReadThroughStore or something similar\n   * that has a cached version of the MediaBlob, but also a way to get\n   * a new (or refreshed) version.\n   */\n  store: BlobStore;\n\n  /**\n   * BlobStores that can resolve a URL into the MediaBlob to save\n   * in the canonical store. This list is evaluated in order.\n   * If not provided, a default list (which involves a DataBlobStore\n   * and a SimpleWebBlobStore) will be used.\n   */\n  resolvers?: BlobStore[];\n}\n\n/**\n * Responsible for converting a URI (typically a web URL) into a MediaBlob.\n * Allows for aliasing / caching of the requested URI and what it resolves to.\n * This MediaBlob is expected to be usable to provide to an LLM, either\n * through the Base64 of the media or through a canonical URI that the LLM\n * supports.\n */\nexport class MediaManager {\n  store: BlobStore;\n\n  resolvers: BlobStore[] | undefined;\n\n  constructor(config: MediaManagerConfiguration) {\n    this.store = config.store;\n    this.resolvers = config.resolvers;\n  }\n\n  defaultResolvers(): BlobStore[] {\n    return [new DataBlobStore({}), new SimpleWebBlobStore({})];\n  }\n\n  async _isInvalid(blob: MediaBlob | undefined): Promise<boolean> {\n    return typeof blob === \"undefined\";\n  }\n\n  /**\n   * Given the public URI, load what is at this URI and save it\n   * in the store.\n   * @param uri The URI to resolve using the resolver\n   * @return A canonical MediaBlob for this URI\n   */\n  async _resolveAndSave(uri: string): Promise<MediaBlob | undefined> {\n    let resolvedBlob: MediaBlob | undefined;\n\n    const resolvers = this.resolvers || this.defaultResolvers();\n    for (let co = 0; co < resolvers.length; co += 1) {\n      const resolver = resolvers[co];\n      if (await resolver.hasValidPath(uri)) {\n        resolvedBlob = await resolver.fetch(uri);\n      }\n    }\n\n    if (resolvedBlob) {\n      return await this.store.store(resolvedBlob);\n    } else {\n      return new MediaBlob({});\n    }\n  }\n\n  async getMediaBlob(uri: string): Promise<MediaBlob | undefined> {\n    const aliasBlob = await this.store.fetch(uri);\n    const ret = (await this._isInvalid(aliasBlob))\n      ? await this._resolveAndSave(uri)\n      : (aliasBlob as MediaBlob);\n    return ret;\n  }\n}\n"],"mappings":"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"}