PHPackages                             byte5/ai-entry-embeddings - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. byte5/ai-entry-embeddings

ActiveStatamic-addon[Utility &amp; Helpers](/categories/utility)

byte5/ai-entry-embeddings
=========================

Statamic addon for generating AI vector embeddings from entry content.

v0.2.0(2mo ago)068↓85%[2 PRs](https://github.com/byte5digital/ai-entry-embeddings/pulls)1GPL-3.0-or-laterPHPPHP ^8.3CI passing

Since Mar 26Pushed 1mo agoCompare

[ Source](https://github.com/byte5digital/ai-entry-embeddings)[ Packagist](https://packagist.org/packages/byte5/ai-entry-embeddings)[ RSS](/packages/byte5-ai-entry-embeddings/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (2)Dependencies (14)Versions (5)Used By (1)

AI Entry Embeddings
===================

[](#ai-entry-embeddings)

AI Entry Embeddings is a Statamic addon that automatically extracts content from entries, splits it into meaningful chunks with metadata, and generates vector embeddings using [Laravel AI SDK](https://laravel.com/docs/master/ai-sdk). Designed for building RAG (Retrieval-Augmented Generation) search experiences on top of your Statamic content.

How It Works
------------

[](#how-it-works)

When an entry is saved in Statamic:

1. The **extraction pipeline** walks through configured fields, producing `ContentChunk` objects -- each with the extracted text, the originating field handle, a dot-notation path (e.g. `page_builder.pricing_block.0`), and structured metadata.
2. Chunks are stored in the `ai_entry_embeddings` PostgreSQL table, replacing any previous chunks for that entry.
3. A queued job calls the Laravel AI SDK to generate vector embeddings for each chunk and writes them back to the database.

The result is a table of chunk-level embeddings you can query with pgvector for similarity search, knowing exactly which section of which entry matched.

Requirements
------------

[](#requirements)

- PHP 8.3+
- Statamic 6.0+
- PostgreSQL with the [pgvector](https://github.com/pgvector/pgvector) extension
- A configured embedding provider via [Laravel AI](https://github.com/laravel/ai) (e.g. OpenAI)

Installation
------------

[](#installation)

```
composer require byte5/ai-entry-embeddings
```

Publish the configuration file:

```
php artisan vendor:publish --tag=config --provider="Byte5\AiEntryEmbeddings\ServiceProvider"
```

Run migrations (this will enable the pgvector extension and create the `ai_entry_embeddings` table):

```
php artisan migrate
```

Configuration
-------------

[](#configuration)

The configuration file is published to `config/ai-entry-embeddings.php`.

### Collections and Fields

[](#collections-and-fields)

You **must** explicitly list which collections and fields to extract. Nothing is extracted by default -- this prevents accidentally exposing sensitive data to the AI.

```
'collections' => [
    'pages' => [
        'fields' => ['title', 'page_builder'],
    ],
    'blog' => [
        'fields' => ['title', 'content'],
    ],
],
```

To use a custom extractor for a specific field, pass an array of extractor classes:

```
'collections' => [
    'pages' => [
        'fields' => [
            'title',
            'custom_field' => [\App\Extractors\MyCustomExtractor::class],
        ],
    ],
],
```

### Embedding Dimensions

[](#embedding-dimensions)

```
'embeddings' => [
    'dimensions' => 1536,
],
```

This value is used both during migration (to size the database column) and at runtime (when calling the embedding API). Changing it after the initial migration requires a new migration to alter the column size, and all existing embeddings must be regenerated since vectors of different dimensions are incompatible.

### Only Published

[](#only-published)

When enabled (default), draft entries are skipped:

```
'only_published' => true,
```

### Field Type Extractors

[](#field-type-extractors)

The addon ships with extractors for common Statamic field types:

Field TypeExtractorBehavior`text``ExtractTextField`Returns the raw string value`textarea``ExtractTextField`Returns the raw string value`markdown``ExtractMarkdownField`Converts Markdown to HTML, then strips to plain text`bard``ExtractBardField`Splits prose and sets into separate chunks`replicator``ExtractReplicatorField`One chunk per set, with nested field extraction`grid``ExtractGridField`One chunk per row, with nested column extraction`select``ExtractSelectField`Returns the option label(s)You can override or add mappings in the `default_field_extractors` config key.

Field types listed in `ignored_field_types` (e.g. `toggle`, `assets`, `date`) are never extracted.

Extending
---------

[](#extending)

### Custom Field Extractor

[](#custom-field-extractor)

Implement `FieldExtractorInterface` and return an array of `ContentChunk` objects:

```
use Byte5\AiEntryEmbeddings\Pipelines\Extraction\ContentChunk;
use Byte5\AiEntryEmbeddings\Pipelines\Extraction\Contracts\FieldExtractorInterface;
use Statamic\Entries\Entry as StatamicEntry;
use Statamic\Fields\Field;

class ExtractMyField implements FieldExtractorInterface
{
    public function extract(
        StatamicEntry $entry,
        string $fieldHandle,
        mixed $value,
        Field $field,
        string $parentPath = '',
    ): array {
        $path = $parentPath !== '' ? "{$parentPath}.{$fieldHandle}" : $fieldHandle;

        return [
            new ContentChunk(
                text: (string) $value,
                fieldHandle: $fieldHandle,
                path: $path,
                metadata: ['field_handle' => $fieldHandle],
            ),
        ];
    }
}
```

Register it either globally in config:

```
'default_field_extractors' => [
    'my_type' => \App\Extractors\ExtractMyField::class,
],
```

Or per-field in a collection:

```
'collections' => [
    'pages' => [
        'fields' => [
            'my_field' => [\App\Extractors\ExtractMyField::class],
        ],
    ],
],
```

### Events

[](#events)

EventWhenPayload`ContentExtracted`Chunks were successfully extracted`ExtractionPayload``EmptyExtractionCompleted`Extraction completed with zero chunks`ExtractionPayload`Control Panel
-------------

[](#control-panel)

The addon registers a navigation section under **AI Tools** in the Statamic control panel, with a landing page and an embeddings overview. Access is gated by the `view AI entry embeddings` permission.

License
-------

[](#license)

This addon is open-sourced software licensed under the GNU General Public License v3.0 (GPL-3.0). See [LICENSE](LICENSE) for details.

###  Health Score

39

—

LowBetter than 85% of packages

Maintenance87

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 97.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~7 days

Total

2

Last Release

84d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/41282cdb98ee1dbc33dd57e79146e6ada49c414f8d0ebc0e94a4dccd571e6585?d=identicon)[byte5](/maintainers/byte5)

![](https://www.gravatar.com/avatar/bfcbb2773515d4b6addd9827f55367d3a1d4d01b4f85906c798a6b33f2733ef6?d=identicon)[jure-knezovic](/maintainers/jure-knezovic)

---

Top Contributors

[![jure-knezovic](https://avatars.githubusercontent.com/u/67332841?v=4)](https://github.com/jure-knezovic "jure-knezovic (33 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

###  Code Quality

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/byte5-ai-entry-embeddings/health.svg)

```
[![Health](https://phpackages.com/badges/byte5-ai-entry-embeddings/health.svg)](https://phpackages.com/packages/byte5-ai-entry-embeddings)
```

###  Alternatives

[statamic/seo-pro

68488.6k](/packages/statamic-seo-pro)[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

135212.4k7](/packages/statamic-rad-pack-runway)[rias/statamic-redirect

29322.9k](/packages/rias-statamic-redirect)[marcorieser/statamic-livewire

A Laravel Livewire integration for Statamic.

23100.9k12](/packages/marcorieser-statamic-livewire)[withcandour/aardvark-seo

Save time and get your Statamic site to rank better with the SEO addon for Statamic.

15131.5k](/packages/withcandour-aardvark-seo)[alt-design/alt-sitemap

Alt Sitemap addon, create a sitemap from Statamic entries

1222.1k](/packages/alt-design-alt-sitemap)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
