# @leumas/adapter-embeddings

Deterministic local embedding capability pack — hash-bucket / TF-weighted 128-dim vectors for text, JSON, CSV, HTML, Markdown, code, email, YAML, signals, and files/folders. Pure JS, no ML runtime...


Deterministic local embedding pack, ported from `tools/a.embeddings`. Pure JS hash-bucket /
TF-weighted vectors (default 128-dim) — **no ML models, no external APIs, no keys**: the same
input always produces the exact same vector, so vectors are comparable across machines and time.

Follows the standard adapter contract (`export default { metadata, adapters }`), loaded by
`shared/engines/middleware`'s registry and callable via `/api/adapters`, MCP, and chatbot
functioncalls. Every tool takes ONE args object.

## Tools

Content → vector (`{ vector, dims }`):

| Tool | Args | Notes |
|---|---|---|
| `embedText` | `{ text, options? }` | Tokenize + bigrams, TF-weighted (stop words down-weighted), hashed into 128 buckets, L2-normalized. |
| `embedJson` | `{ json }` | Object/array or JSON string; flattened keys hashed into buckets. |
| `embedCsv` | `{ csv, options? }` | Each row embedded as text, summed, normalized. |
| `embedHtml` | `{ html }` or `{ path }` | Tags/scripts/styles stripped, then text-embedded. |
| `embedMarkdown` | `{ markdown }` or `{ path }` | Returns `{ sections: [{ type, content, vector }], count }` — one vector per heading/code/text section. |
| `embedCode` | `{ code }`, `{ path }` file, or `{ path }` folder | Comments stripped, then text-embedded. Folder path embeds every code file (`filters`, `maxFiles`). |
| `embedEmail` | `{ eml }` or `{ path }` | Minimal pure `.eml` parse (subject/from/to/body), then text-embedded. |
| `embedYaml` | `{ yaml }` or `{ path }` | Parsed with js-yaml, JSON-stringified, then text-embedded. |
| `embedTimeSeries` | `{ series, options? }` | Statistical feature vector (mean/std/min/max/median/first/last/length). |
| `embedObjectArray` | `{ items, options? }` | One aggregated vector for the whole array. |
| `embedJsonIndex` | `{ items }` or `{ path }` | One vector **per item** — `{ vectors, count }`. |
| `embedEeg` | `{ signal }` | First 64 samples → 64-dim normalized vector. |
| `embedAudio` | `{ samples }` | DFT magnitude spectrum of first 1024 samples. |

Filesystem (path-taking, like a-file-actions):

| Tool | Args | Notes |
|---|---|---|
| `embedImage` | `{ path }` | Size + byte-hash fingerprint vector (rudimentary, no ML). |
| `embedFile` | `{ path, options? }` | Extension-dispatched: json/csv/yaml/html/eml/code/image/text; unknown binaries get a stat-metadata fingerprint. Returns `{ file, kind, vector, dims }`. |
| `embedFolder` | `{ path, filters?, maxFiles? }` | Recursive walk (skips node_modules/dist/.git/build), embeds every file. Returns `{ folder, results, count, truncated }`. |
| `embedMatchingFolders` | `{ path, folders, maxFiles? }` | Finds folders by name under `path`, embeds their immediate files. |

Primitives:

| Tool | Args | Notes |
|---|---|---|
| `tokenize` | `{ text, ngrams? }` | Lowercase alphanumeric tokens (+ optional n-grams). |
| `normalizeVector` | `{ vector }` | L2 normalization. |
| `cosineSimilarity` | `{ a, b }` | Two same-length numeric vectors → `{ similarity }`. |
| `compare` | `{ a, b }` | Embeds two **texts** and returns their cosine similarity (identical texts → 1). |
| `reduceTo3d` | `{ vector }` | First-3-dims reduction for quick 3D visualization. |

## Usage

```js
const { default: embeddings } = await import('@leumas/adapter-embeddings');

const { vector } = await embeddings.adapters.embedText({ text: 'hello world' });
const { similarity } = await embeddings.adapters.compare({ a: 'the cat sat', b: 'a cat sat' });
const { results } = await embeddings.adapters.embedFolder({ path: 'C:/docs', filters: ['.md'] });
```

## DRY boundary

- **No generic vector math here.** `dot`, `l2Norm`, add/scale, etc. belong to
  a-transformation's `vector.*` tools. This pack only exposes the embedding-workflow
  primitives `cosineSimilarity` and `normalizeVector`.
- **Deterministic by design.** No ML runtime, no API keys, no network. For semantic-quality
  embeddings, use a model-backed service; this pack is for cheap, reproducible, offline
  similarity/fingerprinting.
- Dropped from the source: `pdfAdapter` (pdf-parse) and `spreadsheetAdapter` (xlsx) — heavy
  undeclared deps; `mailparser` replaced with a pure `.eml` parser. Only dep: `js-yaml`.


---
Source: shared/engines/adapters/domain/embeddings/README.md
Canonical: https://docs.leumas.tech/p/adapters/adapter-embeddings
