npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mi8y/cap-agents-aicore-vectorstore

v0.2.0

Published

LangChain VectorStore for SAP AI Core Document Grounding in CAP applications

Readme

@mi8y/cap-agents-aicore-vectorstore

npm version License: MIT

A LangChain VectorStore for SAP CAP applications backed by the SAP AI Core Document Grounding service.

SAP AI Core owns document storage, embedding, and retrieval. The package therefore needs no CDS persistence model or client-side LangChain embeddings implementation.

Installation

npm install @mi8y/cap-agents-aicore-vectorstore

Requires:

  • @sap/cds >= 10
  • @langchain/core >= 1
  • An existing SAP AI Core Document Grounding collection
  • SAP AI Core credentials through a service binding or a configured SAP Cloud SDK destination

Configuration

collectionId is required and must be the Grounding collection ID, not its human-readable title.

import { AICoreVectorStore } from "@mi8y/cap-agents-aicore-vectorstore";

const vectorStore = new AICoreVectorStore({
  collectionId: "2b0f4d00-0000-0000-0000-000000000000",
  aiResourceGroup: "default",
  destination: {
    destinationName: "aicore",
    useCache: true,
  },
});

Options:

  • collectionId: string — required Grounding collection ID.
  • aiResourceGroup?: string — value of the AI-Resource-Group header; defaults to default.
  • destination?: object — optional destination configuration. When omitted, the SAP AI SDK uses its default connection, such as an AI Core service binding.
    • destinationName: string — SAP Cloud SDK destination name.
    • useCache?: boolean — whether the SAP Cloud SDK destination cache should be used.

A CAP application can keep these values under cds.requires:

{
  "cds": {
    "requires": {
      "cap-agents-aicore-vectorstore": {
        "collectionId": "2b0f4d00-0000-0000-0000-000000000000",
        "aiResourceGroup": "default",
        "destination": {
          "destinationName": "aicore",
          "useCache": true
        }
      }
    }
  }
}

And then you can use the configuration to instantiate the AICoreVectorStore as shown below:

import cds from "@sap/cds";
import { AICoreVectorStore } from "@mi8y/cap-agents-aicore-vectorstore";

const config = cds.env.requires["cap-agents-aicore-vectorstore"];
export const vectorStore = new AICoreVectorStore(config);

Add documents

LangChain and Document Grounding use different document models:

  • A LangChain document corresponds to a Grounding chunk.
  • Grounding chunks are grouped into Grounding documents.
  • Grounding documents belong to a collection.

Each non-empty addDocuments() call creates one Grounding document with a random UUID v7. Every supplied LangChain document becomes a chunk in that parent document. If a LangChain Document.id is present, it is used as the Grounding chunk ID.

import { Document } from "@langchain/core/documents";

const groundingDocumentIds = await vectorStore.addDocuments([
  new Document({
    id: "cap-overview",
    pageContent: "SAP CAP is a framework for enterprise applications.",
    metadata: { source: "guide.md", topic: "cap" },
  }),
  new Document({
    id: "cap-services",
    pageContent: "CAP services are described using CDS.",
    metadata: { source: "guide.md", topic: "services" },
  }),
]);

Document metadata is stored on its corresponding chunk. Embeddings are generated server-side according to the collection configuration. The returned IDs are the Grounding document IDs reported by the update API, not the input chunk IDs. Passing an empty array returns an empty array without calling the API.

Search and retrievers

const results = await vectorStore.similaritySearch("What is SAP CAP?", 4);

const scoredResults = await vectorStore.similaritySearchWithScore(
  "What is SAP CAP?",
  4,
);

const retriever = vectorStore.asRetriever({ k: 4 });
const documents = await retriever.invoke("What is SAP CAP?");

A retrieved Grounding chunk becomes one LangChain document. The LangChain document ID is the parent Grounding document ID. Grounding document metadata and chunk metadata are merged, and identifiers are added under metadata.grounding:

{
  collectionId: "2b0f4d00-0000-0000-0000-000000000000",
  collectionTitle: "CAP documentation",
  documentId: "0195f4c0-0000-7000-8000-000000000000",
  chunkId: "cap-overview",
}

When document and chunk metadata use the same key, chunk metadata takes precedence. The returned score uses postProcessingScore, then aggregatedScore, then denseRetrievalScore; it falls back to 0 when no score is available.

Queries must not be empty, and k must be a positive integer.

Metadata filters

Filtering uses SAP AI Core's native retrieval filter structures rather than Mongo-style operators:

const documents = await vectorStore.similaritySearch("leave policy", 4, {
  documentMetadata: [
    {
      key: "country",
      value: ["US"],
    },
  ],
  chunkMetadata: [
    {
      key: "language",
      value: ["en"],
    },
  ],
});

The filter accepts the following SAP AI Core retrieval fields:

  • documentMetadata
  • chunkMetadata
  • dataRepositoryMetadata
  • filter
  • scoringConfiguration

The adapter always enforces its configured collection ID, the vector repository type, the langchain-search filter ID, and searchConfiguration.maxChunkCount based on k. These fields cannot be overridden through the supplied filter.

Metadata conversion

Grounding represents every metadata value as string[]. Ingestion converts values as follows:

  • Strings remain strings.
  • Numbers, booleans, and bigints use String(value).
  • Arrays are converted element by element.
  • Objects and null use JSON serialization.
  • undefined properties are omitted.

On retrieval, a single value becomes a string and multiple values remain an array. Values are not automatically converted back to numbers, booleans, or objects.

Delete documents

Deletion requires one explicit parent Grounding document ID:

await vectorStore.delete({ documentId: groundingDocumentIds[0] });

Deleting a Grounding document removes all chunks associated with it. Individual chunks cannot be deleted through this adapter. Calling delete() without a documentId throws, preventing accidental collection-wide deletion. Collection lifecycle operations remain outside the LangChain vector-store adapter.

Static helpers

The static helpers follow the conventional LangChain signatures:

const fromTexts = await AICoreVectorStore.fromTexts(
  texts,
  metadata,
  embeddings,
  config,
);

const fromDocuments = await AICoreVectorStore.fromDocuments(
  documents,
  embeddings,
  config,
);

The embeddings argument is required by the LangChain API but ignored by this implementation because Document Grounding generates embeddings server-side. Both helpers create a vector store and immediately add the supplied content.

Vector operations

addVectors(vectors, documents) ignores the supplied vectors and delegates the documents to addDocuments() so that embeddings are generated server-side.

similaritySearchVectorWithScore() is unsupported because Document Grounding accepts text queries rather than caller-provided query vectors. Use similaritySearch(), similaritySearchWithScore(), or a LangChain retriever instead.

License

MIT License