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.