AI

AI


Adds meaning-based search to barakoCMS. A query for "coffee brewing" finds a post titled "how to pull a good espresso" even though they share no words, because both are compared as embeddings rather than as text.

Embeddings are produced by a self-hosted model — Ollama by default — so content is never sent to a third-party service and there is no API key to manage or leak.

Enable it

dotnet add package BarakoCMS.AI
builder.Services.AddBarakoCMS(builder.Configuration);

var app = builder.Build();
app.UseBarakoCMS();

The package reference plus a restart is the install. AddBarakoCMS finds every module in the application's dependency context, and BarakoCMS:Modules:Enabled decides which of them run (BarakoCMS__Modules__Enabled=AI). Unset, every referenced module runs and the API logs one warning saying so. To name it by hand instead, put modules.Add(new BarakoCMS.AI.AiModule()) in the AddBarakoCMS callback; discovery skips a type the host already added. See MODULES.md in the repository.

What it will and will not index

The boundaries are deliberate, because a search index is an easy place to leak something:

  • Indexes only fields explicitly marked Public in the content type's schema.
  • Searches only Published content whose document sensitivity is Public.
  • A Sensitive or Hidden document is never embedded, so it cannot surface through a similarity search even by accident.

Endpoints

Method & path Purpose Access
GET /api/public/{type}/semantic?q= Semantic search within a content type Anonymous
POST /api/ai/index/{type} Build or rebuild the index for a type Admin / SuperAdmin

Configuration

{
  "Ai": {
    "Enabled": true,
    "EmbeddingBaseUrl": "http://localhost:11434",
    "EmbeddingModel": "nomic-embed-text",
    "SemanticSearchScanLimit": 1000
  }
}

SemanticSearchScanLimit caps how many stored embeddings one search reads for a type, since the search endpoint is anonymous. The default, 1000, is twice what one index run writes. A type with more embeddings than the limit is searched over that many only, and the response says so with "truncated": true.

Filters

Semantic search takes the delivery list's filter[field][op]=value parameters, with the same Public field rule and the same caps (see docs/delivery-api.md in the barakoCMS repository):

GET /api/public/news/semantic?q=flood+warning&filter[Category][eq]=advisory

The filter runs before ranking. The entries that match are read first, up to SemanticSearchScanLimit, and only their embeddings are ranked. When more entries match than the limit, the response sets "truncated": true. A filter on a field that is not Public, an unknown field or operator, a sixth filter and a value over 256 characters each return 400.

The module ships inert: without Ai:Enabled it registers and does nothing, so adding the package cannot change how an existing site behaves. Point EmbeddingBaseUrl at your own Ollama instance. Keep it on a private network — an embedding endpoint exposed publicly is an open compute endpoint for anyone who finds it.

Part of barakoCMS

This is an optional module for barakoCMS, an open-source headless CMS for .NET 10. Every module is published under the barakocms-module tag, so a single search on nuget.org returns the whole set.

Contributions are welcome — including a module icon or other design work. See CONTRIBUTING.md.

Licensed under MIT.

If barakoCMS is useful to you, a star on the repository helps other people find it.