{"version":3,"file":"opensearch.mjs","names":["#opts","#client","#ensure","#dims","#body","#project"],"sources":["../../../src/batteries/vector/opensearch/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/opensearch\n *\n * One adapter for the Elasticsearch / OpenSearch family — they share the same kNN `_search`\n * data model. Each collection is an index with a `knn_vector` field; KNN search uses the\n * native `knn` query, and the neutral filter tree compiles to a bool-query `filter` over\n * `metadata.*` keyword/numeric sub-fields. The document and id live in `_source`.\n *\n * Driver: `@opensearch-project/opensearch` by default. To target Elasticsearch instead,\n * pass a compatible client instance via `options.connection.client` (the `@elastic/elasticsearch`\n * Client has the same `.indices`/`.index`/`.search`/`.deleteByQuery` surface used here).\n */\n\nimport { normalizeScore } from '../helpers'\nimport { BaseVectorStore } from '../contract'\nimport { validateRecords } from '../validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport { isFilterCondition, isRawFilter, isFilterGroup } from '../filters'\nimport {\n  E_VECTOR_STORE_DRIVER_UNAVAILABLE,\n  E_VECTOR_STORE_CONNECTION_FAILED,\n  E_VECTOR_STORE_COLLECTION_FAILED,\n  E_VECTOR_STORE_UPSERT_FAILED,\n  E_VECTOR_STORE_SEARCH_FAILED,\n  E_VECTOR_STORE_DELETE_FAILED,\n  E_VECTOR_STORE_DIMENSION_MISMATCH,\n  E_VECTOR_STORE_UNSUPPORTED_OPERATION,\n  E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR,\n} from '../exceptions'\nimport type { VectorFilter } from '../filters'\nimport type { SearchPlan, UpsertPlan, DeletePlan, CollectionSpec } from '../plan'\nimport type {\n  VectorMatch,\n  VectorStoreCapabilities,\n  BaseVectorStoreOptions,\n  VectorMetadata,\n  DistanceMetric,\n} from '../types'\n\nexport interface OpenSearchVectorStoreOptions extends BaseVectorStoreOptions {\n  /** Connection and authentication parameters for the backend. */\n  connection?: {\n    node?: string\n    auth?: { username: string; password: string }\n    // A pre-built ES/OpenSearch-compatible client. Overrides `node` when provided.\n    client?: unknown\n  }\n}\n\nconst getOpenSearchClient = async () => {\n  try {\n    const mod = await import('@opensearch-project/opensearch')\n    return mod.Client\n  } catch {\n    throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['@opensearch-project/opensearch'])\n  }\n}\n\n// OpenSearch knn_vector space per metric.\nconst spaceType = (metric: DistanceMetric): string =>\n  metric === 'euclidean' ? 'l2' : metric === 'dot' ? 'innerproduct' : 'cosinesimil'\n\n/**\n * Compile the neutral filter tree to an OpenSearch bool-query clause over `metadata.*`.\n * String values use the `.keyword` sub-field for exact match; numbers use range/term.\n */\nexport const translateOpenSearchFilter = (\n  filter?: VectorFilter\n): Record<string, unknown> | undefined => {\n  if (!filter) return undefined\n  if (isRawFilter(filter)) {\n    if (filter.$dialect === 'opensearch' || filter.$dialect === 'elasticsearch') {\n      return filter.$raw as Record<string, unknown>\n    }\n    throw new E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR(['opensearch', String(filter.$dialect)])\n  }\n  if (isFilterCondition(filter)) {\n    const { field, op, value } = filter\n    const f = `metadata.${field}`\n    const kw = `metadata.${field}.keyword`\n    const term = (v: unknown) =>\n      typeof v === 'number' || typeof v === 'boolean' ? { term: { [f]: v } } : { term: { [kw]: v } }\n    switch (op) {\n      case 'eq':\n        return term(value)\n      case 'ne':\n        return { bool: { must_not: [term(value)] } }\n      case 'gt':\n        return { range: { [f]: { gt: value } } }\n      case 'gte':\n        return { range: { [f]: { gte: value } } }\n      case 'lt':\n        return { range: { [f]: { lt: value } } }\n      case 'lte':\n        return { range: { [f]: { lte: value } } }\n      case 'in': {\n        const arr = Array.isArray(value) ? value : [value]\n        const allNum = arr.every((v) => typeof v === 'number' || typeof v === 'boolean')\n        return { terms: { [allNum ? f : kw]: arr } }\n      }\n      case 'nin': {\n        const arr = Array.isArray(value) ? value : [value]\n        const allNum = arr.every((v) => typeof v === 'number' || typeof v === 'boolean')\n        return { bool: { must_not: [{ terms: { [allNum ? f : kw]: arr } }] } }\n      }\n      case 'exists':\n        return { exists: { field: f } }\n      default:\n        throw new E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR(['opensearch', op])\n    }\n  }\n  if (isFilterGroup(filter)) {\n    const { and, or, not } = filter\n    if (and) {\n      const must = and.map(translateOpenSearchFilter).filter(Boolean)\n      return { bool: { must } }\n    }\n    if (or) {\n      const should = or.map(translateOpenSearchFilter).filter(Boolean)\n      return { bool: { should, minimum_should_match: 1 } }\n    }\n    if (not) {\n      const inner = translateOpenSearchFilter(not)\n      return inner ? { bool: { must_not: [inner] } } : undefined\n    }\n  }\n  return undefined\n}\n\nexport class OpenSearchVectorStore extends BaseVectorStore {\n  readonly capabilities: VectorStoreCapabilities = {\n    transactions: false,\n    namedVectors: false,\n    rename: false,\n    rawSql: false,\n    builtInEncoding: false,\n    // Made strongly consistent by refreshing the index after every write (refresh: true /\n    // explicit _refresh), so a write is visible to the next search. The option is a no-op.\n    consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n  }\n\n  #client: any | null = null\n  #dims: Map<string, number> = new Map()\n\n  get #opts(): OpenSearchVectorStoreOptions {\n    return this.options as OpenSearchVectorStoreOptions\n  }\n\n  /** Static availability probe: whether this adapter's runtime driver can load in the current environment. */\n  static isAvailable(): boolean {\n    return typeof process !== 'undefined'\n  }\n  isAvailable(): boolean {\n    return typeof process !== 'undefined'\n  }\n\n  async connect(): Promise<void> {\n    if (this.#client) return\n    const c = this.#opts.connection || {}\n    if (c.client) {\n      this.#client = c.client\n      return\n    }\n    const Client = await getOpenSearchClient()\n    try {\n      this.#client = new Client({ node: c.node ?? 'http://localhost:9200', auth: c.auth })\n    } catch (err) {\n      throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n    }\n  }\n\n  async close(): Promise<void> {\n    if (\n      this.#client &&\n      typeof this.#client.close === 'function' &&\n      !this.#opts.connection?.client\n    ) {\n      await this.#client.close()\n    }\n    this.#client = null\n  }\n\n  async #ensure(): Promise<any> {\n    if (!this.#client) await this.connect()\n    return this.#client!\n  }\n\n  // Unwrap the {body}/direct response shape across client versions.\n  #body(res: any): any {\n    return res && res.body !== undefined ? res.body : res\n  }\n\n  async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n    const client = await this.#ensure()\n    this.#dims.set(spec.collection, spec.vector.dimensions)\n    if (ifNotExists && (await this.hasCollection(spec.collection))) return\n    try {\n      await client.indices.create({\n        index: spec.collection,\n        body: {\n          settings: { index: { knn: true } },\n          mappings: {\n            properties: {\n              vec: {\n                type: 'knn_vector',\n                dimension: spec.vector.dimensions,\n                method: {\n                  name: 'hnsw',\n                  space_type: spaceType(spec.vector.metric),\n                  engine: 'lucene',\n                },\n              },\n              document: { type: 'text' },\n              metadata: { type: 'object', enabled: true },\n            },\n          },\n        },\n      })\n    } catch (err) {\n      throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', String(err)])\n    }\n  }\n\n  async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n    const client = await this.#ensure()\n    if (ifExists && !(await this.hasCollection(collection))) return\n    try {\n      await client.indices.delete({ index: collection })\n      this.#dims.delete(collection)\n    } catch (err) {\n      const msg = String(err)\n      if (ifExists && msg.includes('index_not_found')) return\n      throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', msg])\n    }\n  }\n\n  async hasCollection(collection: string): Promise<boolean> {\n    const client = await this.#ensure()\n    try {\n      const res = await client.indices.exists({ index: collection })\n      const body = this.#body(res)\n      return body === true || body === 200 || res?.statusCode === 200\n    } catch {\n      return false\n    }\n  }\n\n  async renameCollection(_from: string, _to: string): Promise<void> {\n    throw new E_VECTOR_STORE_UNSUPPORTED_OPERATION(['renameCollection', 'opensearch'])\n  }\n\n  async executeUpsert(plan: UpsertPlan): Promise<void> {\n    if (plan.records.length === 0) return\n    validateRecords(plan.records)\n    const client = await this.#ensure()\n    const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection)\n    try {\n      const operations: any[] = []\n      for (const r of plan.records) {\n        let vector = r.vector\n        if (!vector && r.document) {\n          const [v] = await this.encode([r.document], 'document')\n          vector = v\n        }\n        if (!vector) {\n          throw new E_VECTOR_STORE_UPSERT_FAILED(['Record missing vector and document'])\n        }\n        if (expected !== undefined && vector.length !== expected) {\n          throw new E_VECTOR_STORE_DIMENSION_MISMATCH([expected, vector.length])\n        }\n        operations.push({ index: { _index: plan.collection, _id: r.id } })\n        operations.push({ vec: vector, document: r.document ?? '', metadata: r.metadata ?? {} })\n      }\n      await client.bulk({ body: operations, refresh: true })\n    } catch (err) {\n      if (\n        isInstanceOf(err, 'E_VECTOR_STORE_DIMENSION_MISMATCH', E_VECTOR_STORE_DIMENSION_MISMATCH) ||\n        isInstanceOf(err, 'E_VECTOR_STORE_UPSERT_FAILED', E_VECTOR_STORE_UPSERT_FAILED)\n      ) {\n        throw err\n      }\n      throw new E_VECTOR_STORE_UPSERT_FAILED([String(err)])\n    }\n  }\n\n  async executeSearch(plan: SearchPlan): Promise<VectorMatch[]> {\n    const client = await this.#ensure()\n    const metric = this.#opts.metric ?? 'cosine'\n    let queryVector: number[] | undefined\n    if (plan.near) {\n      if ('vector' in plan.near) {\n        queryVector = plan.near.vector\n      } else if ('serverText' in plan.near) {\n        const [v] = await this.encode([plan.near.serverText], 'query')\n        queryVector = v\n      } else if ('id' in plan.near) {\n        try {\n          const res = await client.get({ index: plan.collection, id: plan.near.id })\n          queryVector = this.#body(res)?._source?.vec as number[]\n        } catch {\n          queryVector = undefined\n        }\n        if (!queryVector) {\n          throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n        }\n      }\n    }\n\n    const filter = translateOpenSearchFilter(plan.filter)\n    const size = plan.topK\n    const from = plan.offset ?? 0\n    try {\n      let body: any\n      if (queryVector) {\n        const knn: any = { vec: { vector: queryVector, k: size + from } }\n        if (filter) knn.vec.filter = filter\n        body = { size, from, query: { knn } }\n      } else {\n        body = { size, from, query: filter ?? { match_all: {} } }\n      }\n      const res = await client.search({ index: plan.collection, body })\n      const hits = this.#body(res)?.hits?.hits ?? []\n      return hits.map((hit: any) => this.#project(hit, plan, metric, !!queryVector))\n    } catch (err) {\n      throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n    }\n  }\n\n  #project(hit: any, plan: SearchPlan, metric: string, isKnn: boolean): VectorMatch {\n    const proj = plan.projection\n    const src = hit._source ?? {}\n    const out: VectorMatch = {}\n    if (proj.id) out.id = hit._id as string\n    if (proj.vector && src.vec) out.vector = src.vec as number[]\n    if (proj.document) out.document = src.document as string | undefined\n    if (proj.metadata) out.metadata = (src.metadata ?? {}) as VectorMetadata\n    if (isKnn && typeof hit._score === 'number') {\n      // OpenSearch returns a similarity score (higher = closer); normalize defensively to [0,1].\n      out.score = normalizeScore(hit._score, metric as DistanceMetric, 'similarity')\n    }\n    return out\n  }\n\n  async executeDelete(plan: DeletePlan): Promise<void> {\n    const client = await this.#ensure()\n    try {\n      if (plan.ids && plan.ids.length > 0) {\n        const operations = plan.ids.map((id) => ({ delete: { _index: plan.collection, _id: id } }))\n        await client.bulk({ body: operations, refresh: true })\n      } else if (plan.filter) {\n        const filter = translateOpenSearchFilter(plan.filter)\n        await client.deleteByQuery({\n          index: plan.collection,\n          refresh: true,\n          body: { query: filter ?? { match_all: {} } },\n        })\n      } else {\n        await client.deleteByQuery({\n          index: plan.collection,\n          refresh: true,\n          body: { query: { match_all: {} } },\n        })\n      }\n    } catch (err) {\n      throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n    }\n  }\n}\n"],"mappings":"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"}