Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .aiwg/reports/g-icm-01-interface-inventory.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"control_id": "G-ICM-01",
"project_id": "github.com/chronodeai/agentmemory",
"source_identity": {
"commit_sha": "023433b12303e2b98e4e709c02425493b3e6df48",
"commit_tree_sha": "f87647c615d93a42014f3a4b28603412b0bf7e11",
"inventory_input_sha256": "291b5a4f9644ce81144bf8cc6190e786a834315172a759d24a44a22c5f013855"
"commit_sha": "e241ebb778a9d32a7726ed80b6359fa474139307",
"commit_tree_sha": "bbc5df4d5bfc44e47227e3096455df47a4d64f92",
"inventory_input_sha256": "fd4bf3dffd45c890813b20b16efa791cd6b72f055f65198e8489faffbbe55be8"
},
"public_route_allowlist": [
"GET /agentmemory/livez"
Expand Down Expand Up @@ -2169,7 +2169,7 @@
},
{
"name": "ClipEmbeddingProvider",
"source": "src/providers/embedding/clip.ts:24"
"source": "src/providers/embedding/clip.ts:13"
},
{
"name": "CohereEmbeddingProvider",
Expand All @@ -2185,7 +2185,7 @@
},
{
"name": "LocalEmbeddingProvider",
"source": "src/providers/embedding/local.ts:13"
"source": "src/providers/embedding/local.ts:8"
},
{
"name": "MinimaxProvider",
Expand Down Expand Up @@ -10379,7 +10379,7 @@
{
"surface_id": "PROVIDER:ClipEmbeddingProvider",
"type": "provider-adapter",
"source": "src/providers/embedding/clip.ts:24",
"source": "src/providers/embedding/clip.ts:13",
"auth_control": "processing-policy",
"control_ids": [
"ICM-10"
Expand Down Expand Up @@ -10467,7 +10467,7 @@
{
"surface_id": "PROVIDER:LocalEmbeddingProvider",
"type": "provider-adapter",
"source": "src/providers/embedding/local.ts:13",
"source": "src/providers/embedding/local.ts:8",
"auth_control": "processing-policy",
"control_ids": [
"ICM-10"
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
# src/functions/obsidian-export.ts needs os.tmpdir() + path.join
# rework before Windows can be added back. Tracked as follow-up.
os: [ubuntu-latest, macos-latest]
node-version: [20, 22]
node-version: [20, 22, 24, 26]
steps:
- uses: actions/checkout@v6
with:
Expand All @@ -73,6 +73,9 @@ jobs:
env:
AGENTMEMORY_SECRET: r13-ci-synthetic-only
AGENTMEMORY_PROJECT_CAPABILITY_SECRET: r13-project-capability-synthetic-only
# The R-13 gate fails on any skipped test; run the env-guarded
# real-model embedding smoke instead of letting it skip.
RUN_HF_SMOKE: "1"
R13_RECEIPT_DIR: .r13-receipts/ci
- run: npm run test:r13:validate -- --require-pass .r13-receipts/ci
- name: Upload R-13 evidence
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

## [Unreleased]

## [0.9.30-chronode.4] — 2026-08-25

Upstream sync: port of rohitg00/agentmemory `8c90741` — migration from the deprecated `@xenova/transformers` (silently broken on Node 22+) to `@huggingface/transformers` v4, the renamed continuation of the same Apache-2.0 codebase.

### Changed

- **Local embedding / CLIP / reranker runtime migrated to `@huggingface/transformers` ^4.2.0**. Import specifiers updated in `src/providers/embedding/local.ts`, `src/providers/embedding/clip.ts`, and `src/state/reranker.ts`; `onnxruntime-node`/`onnxruntime-web` are no longer declared directly — they ship transitively with v4. All pipeline call sites now pass `{ dtype: "q8" }` explicitly because v4 defaults to fp32 on Node (v2 defaulted to quantized), keeping model downloads ~3.5x smaller and inference fast. Missing-package errors surface a targeted install hint only for real `ERR_MODULE_NOT_FOUND`; network/model-load failures now propagate their actual message instead of being masked as "install the package".
- **Model cache directory changed upstream**: local embeddings re-download once on first use after upgrading (the v4 package resolves its cache under a different default location than `@xenova/transformers` did). One-time cost per machine; subsequent loads hit the cache as before.
- CI test matrix expanded from Node `[20, 22]` to `[20, 22, 24, 26]` across ubuntu/macos; the R-13 gate now runs with `RUN_HF_SMOKE=1` so the real-model embedding smoke executes instead of counting as a skipped test, and Node 26 is promoted to an accepted R-13 profile.
- Removed `src/xenova.d.ts` (the package ships its own types); added regression tests pinning the `dtype: q8` pipeline contract and reranker positive path.

### Fixed

- **filesystem-watcher silent no-op attach on Node ≥ 23 Linux** (`@agentmemory/fs-watcher` 0.1.2). `fs.watch()` on a nonexistent root reports ENOENT through the async handle's `error` event instead of throwing synchronously, so `start()` attached nothing and never raised "could not watch any of the configured roots"; an explicit existence check now makes the failure deterministic across Node versions. Surfaced by the new ubuntu + Node 24 CI lane.

## [0.9.30-chronode.2] — 2026-08-24

Adversarial-review fixes over the shipped sync wave.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,7 @@ BM25 tokenizes Greek, Cyrillic, Hebrew, Arabic, and accented Latin out of the bo
agentmemory auto-detects your provider. For best results, install local embeddings (free):

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| Provider | Model | Cost | Notes |
Expand Down Expand Up @@ -1270,7 +1270,7 @@ OPENAI_MODEL=qwen2.5-coder-7b-instruct # match the model name from LM St

Reasoning-class models (`o1`-style with `<think>` blocks) can return empty `content` with a `reasoning` field your local server may not surface. If extractions come back blank, switch to a non-reasoning model first. The `OPENAI_REASONING_EFFORT=none` env can also disable thinking on Ollama Cloud thinking models that mirror the OpenAI reasoning schema.

Local embeddings ship out of the box via `@xenova/transformers` — `EMBEDDING_PROVIDER=local` (default) gives you BGE-small entirely on-device. No extra config needed.
Local embeddings ship out of the box via `@huggingface/transformers` — `EMBEDDING_PROVIDER=local` (default) gives you `Xenova/all-MiniLM-L6-v2` (384-dim) entirely on-device. No extra config needed.

### Cost-aware model selection

Expand Down
2 changes: 1 addition & 1 deletion READMEs/README.de-DE.md
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ BM25 tokenisiert Griechisch, Kyrillisch, Hebräisch, Arabisch und akzentuiertes
agentmemory erkennt Ihren Provider automatisch. Für die besten Ergebnisse installieren Sie lokale Embeddings (kostenlos):

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| Provider | Modell | Kosten | Hinweise |
Expand Down
2 changes: 1 addition & 1 deletion READMEs/README.es-ES.md
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ BM25 tokeniza griego, cirílico, hebreo, árabe y latín con tildes de serie. Pa
agentmemory autodetecta tu proveedor. Para mejores resultados, instala embeddings locales (gratis):

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| Proveedor | Modelo | Coste | Notas |
Expand Down
2 changes: 1 addition & 1 deletion READMEs/README.fr-FR.md
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ BM25 tokenise nativement le grec, le cyrillique, l'hébreu, l'arabe et le latin
agentmemory détecte automatiquement votre fournisseur. Pour de meilleurs résultats, installez les embeddings locaux (gratuits) :

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| Fournisseur | Modèle | Coût | Notes |
Expand Down
2 changes: 1 addition & 1 deletion READMEs/README.hi-IN.md
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ BM25 box से बाहर ही Greek, Cyrillic, Hebrew, Arabic, और acce
agentmemory आपके provider को auto-detect करता है। सर्वोत्तम परिणामों के लिए, local embeddings install करें (free):

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| Provider | Model | Cost | नोट्स |
Expand Down
2 changes: 1 addition & 1 deletion READMEs/README.ja-JP.md
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ BM25 は箱から出してすぐにギリシャ文字、キリル文字、ヘブ
agentmemory はプロバイダーを自動検出します。最良の結果を得るには、ローカル埋め込み(無料)をインストール:

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| プロバイダー | モデル | コスト | 備考 |
Expand Down
2 changes: 1 addition & 1 deletion READMEs/README.ko-KR.md
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ BM25는 기본적으로 그리스어, 키릴 문자, 히브리어, 아랍어,
agentmemory는 프로바이더를 자동 감지합니다. 최상의 결과를 위해 로컬 임베딩을 설치하십시오 (무료):

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| 프로바이더 | 모델 | 비용 | 비고 |
Expand Down
2 changes: 1 addition & 1 deletion READMEs/README.pt-BR.md
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ BM25 tokeniza grego, cirílico, hebraico, árabe e latim acentuado de fábrica.
agentmemory autodetecta seu provider. Para melhores resultados, instale embeddings locais (gratuito):

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| Provider | Modelo | Custo | Notas |
Expand Down
2 changes: 1 addition & 1 deletion READMEs/README.ru-RU.md
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ BM25 «из коробки» токенизирует греческий, кир
agentmemory автоматически определяет вашего провайдера. Для лучших результатов поставьте локальные эмбеддинги (бесплатно):

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| Провайдер | Модель | Стоимость | Заметки |
Expand Down
2 changes: 1 addition & 1 deletion READMEs/README.tr-TR.md
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ BM25, Yunanca, Kiril, İbranice, Arapça ve aksanlı Latin'i kutudan çıkar ç
agentmemory sağlayıcınızı otomatik algılar. En iyi sonuçlar için yerel embedding'leri kurun (ücretsiz):

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| Sağlayıcı | Model | Maliyet | Notlar |
Expand Down
2 changes: 1 addition & 1 deletion READMEs/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ BM25 开箱即用支持希腊语、西里尔语、希伯来语、阿拉伯语和
agentmemory 自动检测你的提供者。为获得最佳效果,安装本地嵌入(免费):

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| 提供者 | 模型 | 成本 | 备注 |
Expand Down
2 changes: 1 addition & 1 deletion READMEs/README.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ BM25 開箱即用支援希臘文、西里爾文、希伯來文、阿拉伯文和
agentmemory 自動偵測你的提供者。為獲得最佳效果,安裝本地嵌入(免費):

```bash
npm install @xenova/transformers
npm install @huggingface/transformers
```

| 提供者 | 模型 | 成本 | 備註 |
Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Supply-chain monitoring we already do:

- Dependabot opens PRs for every minor/patch bump on the production dep list (visible in the open PRs).
- Every PR runs the full test suite on ubuntu-latest + macos-latest, Node 20 + 22, before any merge.
- `optionalDependencies` (`@xenova/transformers`, `onnxruntime-node`, etc.) are guarded by `try { await import("...") } catch` so a missing or compromised optional dep cannot break the core runtime path.
- `optionalDependencies` (`@huggingface/transformers`, `onnxruntime-node`, etc.) are guarded by `try { await import("...") } catch` so a missing or compromised optional dep cannot break the core runtime path.

If you find a malicious package in our dep tree, file via the GHSA flow at the top of this document — that's the fastest path to a fixed release on npm.

Expand Down
4 changes: 4 additions & 0 deletions __mocks__/@huggingface/transformers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
throw Object.assign(
new Error("Cannot find package '@huggingface/transformers'"),
{ code: "ERR_MODULE_NOT_FOUND" },
);
2 changes: 1 addition & 1 deletion benchmark/LONGMEMEVAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,6 @@ hf_hub_download(repo_id='xiaowu0162/longmemeval-cleaned', filename='longmemeval_
# Run BM25-only
npx tsx benchmark/longmemeval-bench.ts bm25

# Run BM25+Vector hybrid (requires @xenova/transformers)
# Run BM25+Vector hybrid (requires @huggingface/transformers)
npx tsx benchmark/longmemeval-bench.ts hybrid
```
2 changes: 1 addition & 1 deletion benchmark/REAL-EMBEDDINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Embedding is a one-time cost at ingestion. Search is sub-millisecond after index

## Recommendation

Enable local embeddings by default (`EMBEDDING_PROVIDER=local` or install `@xenova/transformers`).
Enable local embeddings by default (`EMBEDDING_PROVIDER=local` or install `@huggingface/transformers`).
This gives agentmemory genuine semantic search that built-in agent memories cannot match —
understanding that "database performance optimization" relates to "N+1 query fix" and "eager loading".

Expand Down
4 changes: 2 additions & 2 deletions benchmark/real-embeddings-eval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ function generateReport(systems: SystemResult[], obsCount: number): string {
w("");
w("## Recommendation");
w("");
w("Enable local embeddings by default (`EMBEDDING_PROVIDER=local` or install `@xenova/transformers`).");
w("Enable local embeddings by default (`EMBEDDING_PROVIDER=local` or install `@huggingface/transformers`).");
w("This gives agentmemory genuine semantic search that built-in agent memories cannot match —");
w("understanding that \"database performance optimization\" relates to \"N+1 query fix\" and \"eager loading\".");
w("");
Expand All @@ -357,7 +357,7 @@ async function main() {
console.log(`Model loaded. Dimensions: ${testEmbed.length}\n`);
} catch (err) {
console.error("Failed to load Xenova model:", err);
console.error("Install with: npm install @xenova/transformers");
console.error("Install with: npm install @huggingface/transformers");
process.exit(1);
}

Expand Down
6 changes: 3 additions & 3 deletions ci/r13-test-manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"count": 176,
"sha256": "4ef314289367720f8cbe199ca8f2823eea416ec3fa0c861fefcbaf0550d530f1",
"content_sha256": "87a73e351114bac87891494dcb5115636a51608b7c7f8cc0f79ca8809a13145d"
"count": 179,
"sha256": "820931c466afa768c5277d46fc9e638fece5d60cfd58552d0ca07b8a0c1ff522",
"content_sha256": "533be650099bf10f780e09ead8e0a90b53e1bf917b316bf22c3d447f83d659e9"
}
2 changes: 1 addition & 1 deletion integrations/filesystem-watcher/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agentmemory/fs-watcher",
"version": "0.1.1",
"version": "0.1.2",
"description": "Filesystem connector for agentmemory — emits observations on file changes.",
"type": "module",
"bin": {
Expand Down
9 changes: 8 additions & 1 deletion integrations/filesystem-watcher/watcher.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { watch, promises as fsp, readdirSync, statSync } from "node:fs";
import { watch, promises as fsp, readdirSync, statSync, existsSync } from "node:fs";
import { release } from "node:os";
import { resolve, relative, join, extname, sep, basename } from "node:path";
import { randomBytes } from "node:crypto";
Expand Down Expand Up @@ -344,6 +344,13 @@ export class FilesystemWatcher {
const failures = [];
for (const root of this.roots) {
try {
// fs.watch on Node >= 23 reports a missing root through the async
// handle's 'error' event instead of throwing synchronously, so the
// attach below would silently succeed. Check existence up front to
// keep "could not watch any" deterministic across versions.
if (!existsSync(root)) {
throw new Error("root does not exist");
}
if (this.watchMode === "poll") {
this.startPolling(root);
continue;
Expand Down
Loading
Loading