PHPackages                             displace/ai-contracts - 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. [PSR &amp; Standards](/categories/psr-standards)
4. /
5. displace/ai-contracts

ActiveLibrary[PSR &amp; Standards](/categories/psr-standards)

displace/ai-contracts
=====================

Stable, dependency-free PHP interfaces for local-first AI primitives: embeddings, generation, vector search, reranking, transcription.

v0.1.0(1mo ago)0155MITPHPPHP ^8.3CI passing

Since Jun 11Pushed 1mo agoCompare

[ Source](https://github.com/DisplaceTech/ai-contracts)[ Packagist](https://packagist.org/packages/displace/ai-contracts)[ Docs](https://github.com/DisplaceTech/ai-contracts)[ RSS](/packages/displace-ai-contracts/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (3)Versions (2)Used By (0)

ai-contracts
============

[](#ai-contracts)

 **Stable PHP interfaces for local-first AI primitives.**
 Embeddings, generation, vector search, reranking, transcription — zero dependencies, zero implementations.

 [![CI](https://github.com/DisplaceTech/ai-contracts/actions/workflows/ci.yml/badge.svg)](https://github.com/DisplaceTech/ai-contracts/actions/workflows/ci.yml) [![Packagist](https://camo.githubusercontent.com/3b38adac138c6698627b52dcad48317a2581a3c6706e35083e0e78db254e2b4e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f646973706c6163652f61692d636f6e747261637473)](https://packagist.org/packages/displace/ai-contracts) [![PHP 8.3 / 8.4 / 8.5](https://camo.githubusercontent.com/f8c66ec3458748baee370b7844203c334e62735196a3c31b11c504ab609f4be7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e33253230253743253230382e34253230253743253230382e352d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/f8c66ec3458748baee370b7844203c334e62735196a3c31b11c504ab609f4be7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e33253230253743253230382e34253230253743253230382e352d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465) [![Zero dependencies](https://camo.githubusercontent.com/2e7335ac36e73e3008de51759b29de1f8155bdb7ade828067bd6536471d6b0c8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d6e6f6e652d627269676874677265656e)](https://camo.githubusercontent.com/2e7335ac36e73e3008de51759b29de1f8155bdb7ade828067bd6536471d6b0c8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d6e6f6e652d627269676874677265656e) [![MIT License](https://camo.githubusercontent.com/5caa455d8debc46fb23abbadb45a733a937f3910a73fc875c2f7820468e1bb54/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e)](LICENSE)

---

What is ai-contracts?
---------------------

[](#what-is-ai-contracts)

Five interfaces under `Displace\AI\Contracts` that describe what AI primitives *do*, without saying how:

InterfaceContract`Embedder`text in → packed float32 vector out`VectorIndex`id-addressed similarity search with allowlist filtering`Generator`prompt in → completion out`Reranker`query + candidates → best-first relevance scores`Transcriber`audio file in → transcript + timestamped segmentsThe package contains **no implementations and no dependencies** — it is the integration surface between things that provide AI primitives ([ext-infer](https://github.com/DisplaceTech/ext-infer), [ext-turbovec](https://github.com/DisplaceTech/ext-turbovec), hosted APIs, anything else) and things that consume them (LLPhant, NeuronAI, Prism, your application). Frameworks ship the drivers; applications code against the interfaces; providers can be swapped without touching either.

```
composer require displace/ai-contracts
```

The packed-vector contract
--------------------------

[](#the-packed-vector-contract)

Every vector crossing these interfaces is a **packed little-endian float32 binary string** — the output of `pack('g*', ...$floats)` — never a PHP float array. Arrays inflate every coordinate into a zval; packed strings are a single contiguous buffer that moves through FFI and extension boundaries with zero per-element overhead, and batches compose by plain string concatenation:

```
use Displace\AI\Contracts\Embedder;
use Displace\AI\Contracts\VectorIndex;

function indexPosts(Embedder $embedder, VectorIndex $index, array $posts): void
{
    // One packed buffer for the whole batch, one add() call.
    $index->add(
        $embedder->embedBatch(array_column($posts, 'content')),
        array_column($posts, 'id'),
    );
}

function searchPosts(Embedder $embedder, VectorIndex $index, string $query, array $visibleIds): array
{
    // The allowlist composes with a SQL pre-filter:
    //   SELECT id FROM posts WHERE status = 'publish'  →  $visibleIds
    return $index->search($embedder->embed($query), k: 10, allowlist: $visibleIds);
}
```

Nothing above names a concrete engine. Wire in a llama.cpp-backed embedder and an in-process quantized index today, swap either side tomorrow.

Writing an adapter
------------------

[](#writing-an-adapter)

Implementations are intentionally easy to write — here is a complete `Embedder` over ext-infer:

```
use Displace\AI\Contracts\Embedder;
use Displace\Infer\Model;

final class InferEmbedder implements Embedder
{
    public function __construct(private readonly Model $model) {}

    public function embed(string $text): string
    {
        // ext-infer ≥ 0.2 emits the packed contract natively; on 0.1,
        // bridge with pack('g*', ...$vector) instead.
        return $this->model->embed($text)->normalize()->packed();
    }

    public function embedBatch(array $texts): string
    {
        return implode('', array_map($this->embed(...), $texts));
    }

    public function dimensions(): int
    {
        return $this->model->embed('')->dimensions();
    }
}
```

The test suite ships in-memory reference fakes ([`tests/Fake/`](tests/Fake/)) that double as executable documentation of each contract's semantics — the `InMemoryVectorIndex` is a brute-force oracle you can test your own adapter against.

Versioning
----------

[](#versioning)

Interfaces are forever-contracts: methods are never removed or re-signatured within a major version, and new methods only arrive with a major bump (an interface addition is a BC break for every implementor). Pre-1.0, minor versions may still adjust the surface — pin accordingly.

Deliberately out of scope
-------------------------

[](#deliberately-out-of-scope)

**Implementations** (this package never gains a class) · **an orchestration framework** — chains, agents, pipelines, prompt templates belong to the frameworks integrating these contracts · **chat-message abstractions** — every framework already has one; `Generator` is the lowest common denominator they adapt down to · **streaming interfaces** — premature until the underlying local engines ship streaming · **training / fine-tuning**.

License
-------

[](#license)

[MIT](LICENSE) © 2026 Eric Mann / Displace Technologies

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance91

Actively maintained with recent releases

Popularity15

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% 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

Unknown

Total

1

Last Release

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/86bb3fa9fcfe57b8d313e527e9e02bde810951b25722b4717b0953a6c8db41b2?d=identicon)[ericmann](/maintainers/ericmann)

---

Top Contributors

[![ericmann](https://avatars.githubusercontent.com/u/605474?v=4)](https://github.com/ericmann "ericmann (13 commits)")

---

Tags

interfacescontractsaillmTranscriptionembeddingsragvector-search

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/displace-ai-contracts/health.svg)

```
[![Health](https://phpackages.com/badges/displace-ai-contracts/health.svg)](https://phpackages.com/packages/displace-ai-contracts)
```

###  Alternatives

[symfony/translation-contracts

Generic abstractions related to translation

2.6k747.7M692](/packages/symfony-translation-contracts)[symfony/cache-contracts

Generic abstractions related to caching

2.4k332.6M321](/packages/symfony-cache-contracts)[symfony/http-client-contracts

Generic abstractions related to HTTP clients

2.0k428.1M446](/packages/symfony-http-client-contracts)[symfony/contracts

A set of abstractions extracted out of the Symfony components

3.9k65.9M138](/packages/symfony-contracts)[dragon-code/contracts

A set of contracts for any project

1010.2M39](/packages/dragon-code-contracts)

PHPackages © 2026

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