Changelog
All notable changes to this project are documented here.
This project adheres to Semantic Versioning and the Keep a Changelog format.
Older history (pre-2.4.0) is preserved in the GitHub releases page.
[Unreleased]
Planned for 2.7.0.
Added
validateDataset(dataset, { requireExpected, requireSourceIds })checks an evaluation test set before it runs and reports every problem with its case index, id and field, without throwing. A dataset is an array of{ prompt, expected, sourceIds, id, tags }cases or{ cases: [...] };questionandreferenceAnswerare accepted as aliases, and the{ prompt, expected }shapeevaluateRagDatasetreads is valid unchanged. Valid datasets come back normalised incases.runEvaluation(dataset, pipeline)runs every case with citations and evaluation on and returns a JSON report: per-case answers, retrieved ids, scores (faithfulness, relevance, context precision and recall, groundedness, citation coverage, andsourceRecallagainst the case'ssourceIds) and per-metric means. Failed cases are recorded, not thrown; options forconcurrency, a per-casetimeout,signalandonCase. Reports record thelibraryVersion, andcompareConfigurationswarns when two runs used different versions, since scoring can change between releases.compareConfigurations(dataset, { baseline, candidate })compares two runs, where each side is a pipeline or a saved report, and reportsregressed, per-metric deltas, and the cases that now fail or dropped by more thancaseTolerance.tolerance(default 0.02) sets the allowed drop in a metric's mean.generateSyntheticDataset(documents, { llm, count })drafts a test set: an LLM writes question and answer pairs about one document at a time, and each case records the document insourceIds. Answers their document doesn't support (bycomputeFaithfulness), repeated questions, malformed replies and short documents are skipped and listed with a reason. Cases are taggedsyntheticand markedreviewed: false.rag-pipeline generate-dataset --output <file>does the same from the index with the configuredllm, and won't overwrite a file without--force.rag-pipeline eval <dataset>runs a.jsonor.jsonltest set through the configured pipeline and exits 1 when a case fails, a metric is below its--min metric=value, or the run regressed from a--baselinereport.--outputsaves the run as a baseline,--reportwrites a standalone HTML page (.html) or a Markdown summary for a pull request comment, and--jsonprints the verdict. Also--tolerance,--case-tolerance,--concurrency,--timeoutand--top-k.DevilsDev/rag-eval-action, a GitHub Action that runsrag-pipeline evalon pull requests, compares them with the default branch's report from the Actions cache, posts a summary comment that later runs update, and fails the check when scores drop. Itsv1is published with this release.renderEvaluationReport(Markdown or HTML) andevaluationVerdictfor the same reports in code.sourceIdsmatch a retrieved result'sidor itsmetadata.source, so a case can name a file when the index stores chunks of it.
Fixed
- A bad option value (
--top-k 0,--min speed=1) printed a stack trace; the CLI now prints a one-line error naming the option and exits 1.
2.6.2 - 2026-10-29
Fixed
npm installfailed on machines without husky installed globally. Every release from 2.2.1 to 2.6.1 declared"postinstall": "husky install". husky is a development tool that isn't installed in users' projects, so installing the package failed withhusky: not found(or'husky' is not recognizedon Windows) on clean machines and CI runners. The hook now runs fromprepare, which npm runs only in this repository, and the pack smoke test fails if the package has any install-time script. No code changes.
2.6.1 - 2026-10-29
Documentation only; no code changes.
Changed
- README covers the 2.6.0 features, so the npm package page shows
them:
checkAnswerfor answers from other frameworks, the/testingentry, caching, thequery--explain,--trace,--statsand--streamingoptions,OpenAIConnectorbaseURLand the AI SDK adapter. - StackBlitz examples checked: the basic pipeline, OpenAI with Pinecone (offline mock) and the Fastify service each install and run. The docs now say to reload if StackBlitz stalls while cloning.
2.6.0 - 2026-10-29
Added
OpenAIConnectorbaseURLfor OpenAI-compatible APIs (Groq, Together, the Hugging Face router, vLLM, LM Studio, Ollama's/v1endpoint). With a custombaseURLthe key is never read fromOPENAI_API_KEY, so an OpenAI key is not sent to another provider; passapiKey, or omit it for local servers that need none.validatePlugin(stage, plugin, { registry })returns{ valid, errors, warnings }for a plugin without throwing, for use in plugin tests.registry: truealso applies the rulespluginRegistry.register()enforces.ParallelEmbeddermode('auto','batch','single').checkAnswer({ question, answer, sources })checks an answer from any framework (LangChain, LlamaIndex, Mastra, the AI SDK, your own code) against its sources:grounded,groundedness, theunsupportedsentences, per-sentencecitationsandevaluationscores. Sources may be strings,{ id, content }, LangChain Documents or LlamaIndex nodes;normalizeSourcesis exported for the conversion alone.- Caching:
createRagPipeline({ cache })caches query embeddings, retrieval results and answers (true, a store, or per layer with time to live).MemoryCache(LRU and TTL) andRedisCache(node-redis or ioredis) are included; anyget/setstore works. A layer caches only when its component identifies itself (getCacheKey(role)orcacheKey; all built-ins do), retrieval is keyed by the store's state and the query vector, answers by the exact documents and generation options, and answers are not cached when the temperature is above 0. Retrieval is cached beforefilterResultsand the reranker, so guardrail ACLs run on every request. Nothing from a failed, aborted or timed-out run, or from an unfinished stream, is stored. Results carrycacheper layer and the pipeline hascacheStats(). @devilsdev/rag-pipeline-utils/testing: deterministic, offline test helpers.HashEmbedder,EchoLLM(answers with the top document or a set answer, records every call, streams),fixtures.documentsandcreateTestPipeline(). Shares classes with the main entry and is not loaded by it.computeSemanticSimilarity(answer, reference, { embedder }): cosine similarity of the two embeddings, 0 to 1.checkAnsweradds it asevaluation.scores.semanticSimilaritywhen given areferenceAnswerand anembedder.rag-pipeline queryoptions:--trace(time per stage),--explain(passage scores, and the passages supporting each answer sentence, with unsupported sentences flagged),--stats(latency, estimated tokens and cost),--streamingand--timeout <ms>; global--quiet.--jsonincludes trace, stats and explanation when asked.createAiSdkAdapter({ ai, embeddingModel, languageModel })wraps Vercel AI SDK models as anembedderand anllmforcreateRagPipeline(), with streaming,embedManybatching and the run'sAbortSignal. You pass the AI SDK functions, so it is not a dependency and works with AI SDK 5, 6 and 7 from ESM or CommonJS. The RAG system prompt is sent as bothinstructions(AI SDK 7) andsystem(5 and 6). Tested against AI SDK 6 and 7 with their mock models.
Changed
- Faster CLI. Commands load only their own dependencies:
--helptakes about 0.5 s andqueryabout 0.5 s instead of about 3.6 s. Loading the CLI drops from 1281 modules and 93 packages to 55 and 13. The HTML, Markdown and CSV loaders loadjsdom,markedandcsv-parsewhen they read a file. - Faster import.
require('@devilsdev/rag-pipeline-utils')takes about 125 ms instead of about 515 ms and loads 31 modules from 9 packages instead of 245 from 54 (published bundle, Node 22).axios,jsonwebtoken,ajvandchokidarnow load when the feature that needs them is first used (the Anthropic, Cohere and Ollama connectors,JWTValidator, plugin registration and config validation, hot reload). The sharedpluginRegistryloads its contracts on first use; registries created withnew PluginRegistry()still load them in the constructor.
Fixed
ExecutionTracer.exportTraces('json')threw "circular structure" with the defaultcaptureOutputs: true: traces stored the live result, which carries the trace. Traces now store JSON snapshots, which also keeps later changes to a result out of its recorded trace.ParallelEmbedderfailed with the built-in connectors, which embed one string at a time, because it always calledembed(batch)with an array. In the default'auto'mode it now embeds texts one by one for those connectors and usesembedBatch(texts)when an embedder has it; other embedders are still called with the array.
2.5.0 - 2026-10-28
Added
- Cancellation:
createRagPipelinecreates an AbortController per run and passes its signal to every component (retriever.retrieve({ signal }),embedder.embedQuery/embed(text, { signal }),reranker.rerank(q, docs, { signal }),llm.generate(q, docs, { signal })); a newoptions.signallets callers cancel. All built-in connectors and rerankers honour it.AgenticPipelineandIterativeRetrieverpropagate it too. QueryPlanner.plan(query, { llm, signal }): LLM-proposed sub-queries with strict JSON validation and heuristic fallback (returns a Promise);AgenticPipelineoptionenableLlmPlanning(defaultfalse).checkNumericConsistency,extractNumbers,detectInjectionandPRICING_METADATAexports.- Opt-in
detectInjectiononRetrievalGuardto scan retrieved documents for indirect prompt injection. CostCalculator: pricing provenance (source,asOf,verified), apricingoverride, one-time unknown-model warnings (RAG_UNKNOWN_MODEL_PRICING), longest-match model resolution.EmbeddingRerankercacheSize(LRU of document embeddings) andconcurrencyoptions;MemoryRetrievereviction: 'fifo'option.- Plugin signatures:
computeContentDigest(), a signedcontentDigestthat binds plugin code, opt-inrequireContentDigestandrequireSignedPlugins, andregister()'s optional{ content }argument. JWTValidatoroptionssingleUseTokens(defaulttrue) andmaxTrackedJtis(default 100000).AuditLoggerreads its key fromencryptionKeyorRAG_AUDIT_ENCRYPTION_KEY;requireEncryption: truemakes a missing key an error..env.examplefordocker compose.npm run test:serialandnpm run format:check.- Working CLI workflow:
rag-pipeline init,ingest <path>,query <question>andrunnow do real work against a persistent local index.initwrites a pipeline of built-in components (--template local | openai | ollama | anthropic, or interactive prompts in a terminal). FileVectorStore(exported): JSON-file vector index with atomic writes, embedder/dimension tracking and per-source re-ingestion..ragrc.jsonpipeline resolution: entries{ stage, name, config }resolve to built-in components, custom plugin modules underplugins, or plugins registered onpluginRegistry.rag-pipeline serveand a workingDevServer: local HTTP API (GET /health,POST /query) bound to 127.0.0.1, JSON only, 64 KB body limit, no CORS.LocalEmbedder.getState()/setState().rag-pipeline hub install <source>installs plugins from a local directory,.tgz, single.jsfile,npm:<package>or a registry (sha256-verified). It contains extraction to.rag/plugins, runs a static security scan (high-risk findings block unless--allow-risky), checks the stage contract in a separate process, and registers the plugin in.ragrc.json.PluginHub.installPlugin()uses the same installer.rag-pipeline hub certify submit|check <path>scores a local plugin from its files (contract, security scan, tests, documentation) against the BASIC/VERIFIED/ENTERPRISE automated thresholds.rag-pipeline hub listlists plugins registered in the config.rag-pipeline initsetup wizard: chooses the embedder, LLM, retriever and an optional reranker, using only built-ins or custom plugin modules. Connector options are pre-filled with the connector defaults. Each custom plugin is loaded and its stage method checked before it is accepted. The wizard reports which API key environment variables are missing, can run a connection test on request, and previews the JSON before writing.rag-pipeline ai, built on the configured pipeline and index:ai train embedding [path]refits thelocalTF-IDF embedder and re-embeds the index;ai benchmarkreports measured p50/p95/mean latency per stage;ai feedback <question> <docId> --rating up|downstores votes in.rag/feedback.jsonandai searchapplies them as a capped, explained score adjustment;ai multimodal process <path>reports type, characters and chunks for text files (images exit 1: no built-in connector accepts image input).
Deprecated
- Experimental modules moved to
@devilsdev/rag-pipeline-utils/experimental:ModelTrainingOrchestrator,FederatedLearningCoordinator,MultiModalProcessor,AdaptiveRetrievalEngine,SSOManager,SAMLProvider,OAuth2Provider,ActiveDirectoryProvider,OIDCProvider,TenantManager,ResourceMonitor,DataGovernanceManager/DataGovernance,PluginSandboxandPluginCertification. They are simulated or incomplete (random metrics, SSO that accepts any code outside production and does not verify SAML or OIDC tokens, random quotas, erasure that deletes nothing, a non-functional sandbox, fixed certification scores); see the Experimental docs page. Their main-entry exports still work but emit a one-timeDeprecationWarning(RAG_DEP_*codes) when used, are marked@deprecatedin the types, and will be removed from the main entry in the next major release. The same classes are shared by both entries, soinstanceofchecks keep working.
Removed
- Unused CLI config templates under
src/cli/templates/(old format, referenced a schema path that did not exist). - Ten unreachable duplicate modules under
src/ai/and the internalsrc/dag/enhanced-dag-engine.js(never reachable from the package entries; the exported classes are unchanged). - semantic-release configuration and dependencies (releases use
npm publish --provenancefrom the release workflow), duplicate.eslintrc.jsonand.babelrc, about 50 one-off fix scripts and theirci:*npm scripts, the trackedjunit.xml, and 14 test suites that never exercisedsrc/(fake pipelines, mocks, empty timing loops). - CLI placeholders that printed success without doing anything (
ingest,query,doctor,validate,plugin search|install|publish) and options that had no effect (--trace,--stats,--parallel,--streaming,--max-memory,--preview,--validate,--explain,--abort-timeout,--quiet,config show --format). - The interactive wizard built on hard-coded mock registry data.
- The unregistered
src/cli/commands/ai-ml*command modules: federated learning, LLM fine-tuning,ai train status|deploy,ai dashboard, adaptive profiles and multimodalsearch/describe. They called methods missing from thesrc/aiengines, exited 0 on failure and printed hard-coded or simulated numbers. Thesrc/ailibrary modules are unchanged. - Unreachable modules that were never exported or registered:
src/dx/(including a realtime debugger exposing an unauthenticated WebSocket),src/cli/commands/{dx,docs}.js,src/cli/input-sanitization-middleware.js,src/cli/plugin-marketplace-commands.js,src/query.js,src/ingest.js,src/pipeline/pipeline.js,src/core/pipeline-factory.js. The packageexportsmap only exposes.and./cli, so these were never public.
Fixed
evaluateRagDatasetscores the generated answer; it scored the retrieved documents, so every case failed with zero scores.RetrievalGuardwithenforceACLalso reads a top-levelacl/requiredRoleon results that havemetadata(it read onlymetadatathen).createRagPipeline: timeouts now cancel work and no stage starts after an abort (a timeout still resolves{ success: false, error: 'Execution timeout' }; a caller abort resolves'Execution aborted'). Without an llm it runs retrieval only and returnsanswer: nullinstead of'ok'. Stream mode withcitationsorevaluateends with one{ token: '', done: true, citations, evaluation }chunk. The artificial 5 ms delay is removed.- Connectors retry only transient failures (network, 408/409/425/429/5xx)
with exponential backoff, jitter and
Retry-After; SDK-internal retries are disabled. API keys are read at construction, and calls without a key fail fast withMISSING_API_KEY. MemoryRetrieverenforcesmaxDocumentsand rejects mismatched vector dimensions instead of truncating them.AuditLoggerno longer encrypts with a random per-process key that made logs unreadable after a restart; legacycreateCipherrecords decrypt on Node 22+.JWTValidator/jwt-confighonour an explicitclockTolerance/notBeforeToleranceof 0 (it became 30); the expired-token test is enabled.loadPluginsFromJsonawaits registration and verifies signed manifests and plugin files before importing them.rag-pipeline init: the connection test aborts its calls after the 15 s timeout and the CLI exits afterwards.- Benchmarks accept
--iterations=N, no longer abort on the retry benchmarks' deliberate warm-up failures, and exit when done. - Docs generation no longer hangs: the JSDoc regex backtracked
exponentially on an unterminated
/**. - Tests run in parallel again (a suite destroyed the Jest worker's own
stdio streams), no longer rewrite tracked fixtures, and coverage works on
Windows (the test setup no longer patches
path.resolve). - Package import:
require()/importof 2.4.5 failed in every clean install withCannot find module 'isolated-vm'.isolated-vmis now loaded only whenPluginSandboxruns and is an optional peer dependency;pino-prettyis an optional peer as well. Added the missingajv-formatsandmarkeddependencies, pinnedchalkto 4.x (5.x is ESM-only), removed unuseddotenv. Importing the bundle no longer prints "Missing Contract" warnings. A tarball smoke test (npm run smoke:pack) now runs in CI and before publish. createRagPipeline: theembedderresult was computed and discarded, so vector retrievers never received aqueryVector. Plugins registered on the exportedpluginRegistryare now resolvable by name, and the timeout timer is cleared when a run finishes.MemoryRetrieverthrows a clear error when noqueryVectoris given instead of crashing inside cosine similarity.- README / docs quick start now passes an
embedder; as previously written it could not retrieve anything fromMemoryRetriever. - Citations with zero retrieved documents no longer fail the run; every sentence is reported as unsupported.
HybridRetrieverpasses the full request (includingqueryVector) toretrieve(), so vector results are no longer silently dropped, and throws when every retriever fails.- Guardrails: the retrieval guard (ACL, relevance, freshness) now runs
before generation via the new
options.filterResultshook; removed documents are reported by id only; strict-mode blocks no longer return the raw answer; PII is redacted in citations and evaluation details too. AuditLogger: tenant/user/action filters never matched, so queries and compliance reports returned every tenant's records. Encryption now usescreateCipherivwith a random IV per field (it threw on Node 22 and reused the nonce on Node 18/20). The integrity hash now covers action and tenant.InputSanitizer: a regex state bug let command-injection payloads through after a previously blocked input.LLMRerankersends an actual ranking prompt instead of the raw question, keeps documents the LLM omits, and honourstopK.- Agentic RAG: with an
embedder, each sub-query and refined query is embedded on its own instead of reusing the original query vector. - TypeScript: 52 runtime exports (citations, guardrails, hybrid
retrieval, agentic RAG, connectors, rerankers, GraphRAG, ...) had no
declarations. They are now generated from JSDoc at build time into
dist/types/and re-exported fromdist/index.d.ts; the build fails if any export is undeclared, and the smoke test compiles a TypeScript consumer. doctor/validatereport real findings (unknown components, missing stages, missing API keys, broken custom plugins) and exit 1 on errors.doctor --auto-fixno longer lets callers re-enable a shell, no longer strips Windows path separators, and runs npm on Windows.hub(aliasplugin) commands are registered. There is no default registry (the old default host does not exist): pass--registry <url>or setRAG_PLUGIN_REGISTRYfor registry operations.- Hot reload ignore patterns work again (chokidar 4 dropped glob support) and only JavaScript changes trigger a reload.
loadRagConfig()accepts a config file path as well as a directory and no longer logs to stdout.LocalEmbedderproduced all-zero vectors for corpora of two or fewer documents (IDF is now smoothed).- Logger: console-style calls such as
logger.error("Failed:", msg)no longer log the message as one key per character.
Changed
-
Documentation: the README is rewritten with use cases whose code runs in CI (
__tests__/docs/readme-examples.test.jsexecutes every README example), and.ragrc.json's JSON schema (.ragrc.schema.json, shipped in the package) now describes thepipeline+pluginsformat the CLI andloadRagConfig()actually use. -
Metric changes:
- Context recall now measures how much of a reference (ground-truth) answer
the retrieved documents support. Pass it via
PipelineEvaluator.evaluate(result, { referenceAnswer })orrun({ options: { evaluate: true, referenceAnswer } }). Without one,scores.contextRecallis omitted,details.contextRecallis{ score: null, skipped: true, reason }, andmetadata.metricsSkippedlists it. computeGroundednessis a weighted mean over the available components; without a reference it is(0.4 * faithfulness + 0.3 * contextPrecision) / 0.7.- Claim support checks numbers: a sentence whose numbers (digits, decimals,
percentages, number words) are not in the source scores below 0.4 and is
not grounded. This affects citations, faithfulness, recall,
PostGenerationGuardandSelfCritiqueChecker. "20" equals "twenty".
- Context recall now measures how much of a reference (ground-truth) answer
the retrieved documents support. Pass it via
-
createRagPipelineresults always includeanswerwhen an llm is configured. -
QueryPlannersplits only at clause or question boundaries, keeps "salt and pepper"-style phrases intact, and expands comparisons into one sub-query per entity plus the comparison; results carrysource. -
Prompts: built-in connectors put retrieved context in the user message as delimited, untrusted reference data, with a system prompt telling the model to treat it as data. Answers may differ.
-
PreRetrievalGuardreturns the query unchanged (no partial deletion) and reports detections ininjection; strict mode still blocks. Detection normalises input first. To cut false positives, bare "act as", "jailbreak", uppercase "DAN", mid-line "system:" and "you are now ready" are no longer flagged; chat role markers, prompt-exfiltration phrasing and normalisation bypasses now are. -
CostCalculatorpricesgpt-4o-mini-*andclaude-3-5-sonnet-*correctly (previously gpt-4 pricing and $0);customPricingentries withoutunitdefault to per-1000 tokens. Built-in prices are marked unverified: theirasOfis when they were added, not when they were checked. -
EmbeddingRerankerlimits concurrency to 4 by default; callclearCache()after retraining an embedder. -
AuditLoggerwith encryption enabled and no key now disables encryption with a warning instead of using a throwaway key. -
Plugin trust store is empty by default (the placeholder key is gone).
-
docker composerequiresPOSTGRES_PASSWORD,REDIS_PASSWORDandGRAFANA_ADMIN_PASSWORD, publishes ports on 127.0.0.1 only, and drops the debugger port and the Prometheus lifecycle API; the image build fails on critical runtime vulnerabilities. -
CI: one
ci.ymlworkflow (required checksTest & Lint (18|20|22)) that also enforcesformat:checkand the tarball smoke test, and runs for pull requests into any branch.npm testruns Jest in parallel. -
DevServernow really listens:start()binds port 3000 by default (passport: 0for a free port), so existing callers may seeEADDRINUSE. Default host is127.0.0.1(waslocalhost), defaultwatchPathsis[](was./src/plugins,./src/mocks), and requests must use a loopbackHostheader while bound to loopback. -
loadRagConfig()error messages now include details (Config validation failed: ...,Invalid JSON in config file <path>: ...) and it no longer logs. -
rag-pipeline plugin/hubregistry operations require--registry <url>orRAG_PLUGIN_REGISTRY.hub certify submittakes a local plugin path and reports computed scores; it previously issued certificates from fixed placeholder scores.PluginHub.installPlugin()now installs into<project>/.rag/pluginsand registers the plugin in the config (it previously only wrotemetadata.jsontolocalCacheDir), andgetInstalledPlugins()reads the config. -
FileVectorStoreindex files store mostly-zero vectors sparsely and round values to 7 significant digits (about 10x smaller for thelocalembedder). -
Grounding scores (citations, faithfulness, context precision/recall, groundedness,
PostGenerationGuard,SelfCritiqueChecker) now measure the share of a sentence's content words found in a document, optionally IDF-weighted. They previously used Jaccard similarity against the whole document, which shrinks with document length: an answer copied verbatim from a ~70-word chunk scored 0. Scores will be noticeably higher for grounded answers. -
Default per-sentence similarity threshold raised from 0.3 to 0.5 (
CitationTracker.similarityThreshold,PipelineEvaluator.threshold, faithfulness/recall/hallucination-detectorthreshold). Aggregate thresholds (groundednessThreshold,approvalThreshold) are unchanged. -
The tokenizer keeps non-ASCII letters (
Políticano longer becomespoltica) and splits on newlines and hyphens instead of gluing words together. This also affects BM25, BLEU/ROUGE and the scoring reranker. -
RetrievalGuardwithenforceACLnow fails closed whencontext.userPermissionsis missing. -
CitationTracker.track()non-array error message is now "retrievedDocs must be an array".
Security
- Production dependencies:
npm audit --omit=devreports no high or critical findings (axios ^1.21.0; overrides for fast-uri, follow-redirects, form-data, ws and zod). - Experimental SSO: the development bypass that accepted any authorization
code requires
devBypass: trueand a non-productionNODE_ENVand is refused in production; OIDC id_tokens are validated (JWKS signature, iss, aud, exp, nonce); OAuth2/OIDC use PKCE (S256);redirect_uricomes only from configuration; callbacks must match the stored login request's provider. - Plugin signatures: Ed25519 verification works (
crypto.verifywith KeyObjects); a signedcontentDigestbinds plugin code and is always enforced when present. AuditLoggercompares HMAC signatures in constant time;JWTValidator's replay store is bounded and expires entries.- Retrieved documents are no longer placed in the LLM system role; prompt injection detection normalises homoglyphs, leetspeak and zero-width characters.
.secretsis no longer tracked in git (rotate anything it held) and is excluded from Docker builds.
Known limitations
- Grounding is lexical plus a numeric-consistency check. Not checked: negation ("not twenty days"), units ("20 hours" vs "20 days"), ordinals, a lone "one", differently split decimals, and claims that combine facts from several documents. Document-side matching is lenient ("twenty-five" in a source also supports "twenty" or "five").
- The
openaiSDK stays on 4.x: newer majors need Node 20+ and will come with 3.0.csv-parsehas one moderate advisory whose fix is a major release. - Experimental SSO cannot refresh OIDC sessions, and
SAMLProviderrefuses to authenticate. AuditLogger's HMAC signing key is random per process unlesssigningKeyis passed, soverifyIntegrityflags records written before a restart.
2.4.5 - 2026-04-19
Changed
- Supply chain: first release published via GitHub Actions OIDC trusted
publishing with
--provenanceattached. Tarball now ships with a SLSA build provenance attestation signed via Sigstore; consumers can verify the git-commit → tarball-bytes chain withnpm audit signatures. No long-livedNPM_TOKENinvolved. - Publish workflow (
.github/workflows/release.yml): switched fromNODE_AUTH_TOKENto OIDC, upgraded npm CLI to 11.5.1+ at job start, added--provenanceand--ignore-scriptsto the publish step.
No API, behavior, or documented-surface changes from 2.4.4.
2.4.4 - 2026-04-16
Added
BENCHMARKS.md(root, ships in tarball) — methodology-first benchmarks doc covering what we measure, what we don't, how to run the suite, environment disclosure template, JSON report schema, end-to-end harness template for benchmarking your own stack, interpretation guide (percentiles, throughput, memory), common pitfalls, and a CI regression pattern.SEMVER.md(root, ships in tarball) — API stability policy. Defines public surface, what counts as breaking, deprecation process (one-minor warning window minimum), supported runtimes, TypeScript and ESM/CJS commitments.docs-site/docs/Security-Capabilities.md— capability matrix distinguishing what's battle-tested (🟢) vs. recommended practice (🟡) vs. example code requiring hardening (🟠) vs. out of scope (🔴), across pre-retrieval, retrieval-time, and post-generation guardrails plus supply-chain, auth, logging, input validation, and data governance.docs-site/docs/Concepts-Core.md,Concepts-Connectors.md,Concepts-Evaluation.md,Concepts-Guardrails.md— four conceptual-module overviews mapped to a futurerag-core/rag-connectors/rag-eval/rag-guardrailspackage boundary, so reviewers can reason about blast radius without us splitting the codebase.docs-site/docs/Comparison.md— honest comparison vs. LangChain.js and LlamaIndex.TS, including where we lose and a decision framework. Currency dated to April 2026.examples/fastify-rag-demo/— runnable end-to-end RAG service: Fastify 5 + OpenAI + in-memory retriever + 3-layer guardrails- citations + evaluation. Ships with Dockerfile, Fly.io
fly.toml, Railwayrailway.json, ingest + smoke-test scripts, and a complete README. ~150 lines ofserver.js.
- citations + evaluation. Ships with Dockerfile, Fly.io
examples/README.md— index of runnable examples with contribution guidance.
Changed
- README "Documentation" section now links to BENCHMARKS, SECURITY, CHANGELOG (added in 2.4.3) plus SEMVER, the Security Capabilities matrix, the Comparison page, and the runnable demo.
- Sidebar adds two new categories: "Concepts" (4 pages) and a Comparison page under Overview. Security-Capabilities slotted under Enterprise.
2.4.3 - 2026-04-16
Security
- axios upgraded from
1.8.4→1.15.0, closing two critical advisories:- GHSA-fvcv-3m26-pcqx — unrestricted cloud metadata exfiltration via header injection chain
- GHSA-3p68-rc4w-qgx5 — SSRF via
NO_PROXYhostname normalization bypass
- follow-redirects transitive patched for moderate auth-header leak on cross-domain redirects (GHSA-r4q5-vmmm-2653)
- Supply-chain CI workflow now runs
npm auditwith--omit=devand scopes the license allowlist to runtime deps — dev-only licenses no longer break the build, since they don't ship in the published tarball - Added
UnlicenseandCC-PDDCto the license allowlist as legitimate public-domain dedications
Added
SECURITY.md— responsible-disclosure policy with triage SLAs and safe-harbor languageCHANGELOG.md— this file
Changed
package.jsondescription updated to match the new positioning: "Composable RAG for Node.js — with built-in evaluation, citations, guardrails, and observability." (previously the long "comprehensive enterprise-grade toolkit" line)
2.4.2 - 2026-04-16
Changed
- License: GPL-3.0 → MIT. Removes adoption friction for commercial and closed-source consumers.
- README repositioned around three core primitives —
pipeline,plugin,connector— instead of export counts. New sections: Who This Is For, Use Cases (Document Q&A with citations / internal knowledge assistant with evaluation / enterprise service with guardrails). - Docs-site homepage code example switched from CommonJS
require()to ESMimport, matching the README and the package's dual-mode export. - Docs-site stat cards replaced unverified "<200ms retrieval latency" with verifiable "MIT License" + "3 Core Primitives".
- Kubernetes deployment examples in
docs-site/docs/Deployment-Kubernetes.mdbumped from2.3.1to2.4.2(6 occurrences). - Algolia DocSearch facet filter and docs version label updated to
2.4.2.
2.4.1 - 2026-04-15
Changed
- Complete README rewrite for professional npm.js rendering — concise structure, ASCII architecture diagram (replaces Mermaid, which npm.js does not render), 21 keywords for discoverability.
- Additional internal files excluded from the published tarball (
src/cli/plugin-marketplace-commands.js, example folders).
2.4.0 - 2026-04-14
First public release on the 2.4 line, introducing the v2.4 feature set.
Added
- GraphRAG — knowledge-graph construction with entity/relationship extraction and graph traversal retrieval.
- Streaming embeddings — SSE and WebSocket adapters with backpressure control.
- Advanced reranking — cascaded reranker combining BM25, embedding similarity, and LLM scoring.
- Performance dashboard — bottleneck detection, execution tracing, token and cost tracking, budget enforcement.
- MCP integration — expose pipelines as Model Context Protocol tools.
- 3-layer guardrails — pre-retrieval (prompt-injection detection, topic filtering), retrieval-time (minimum relevance thresholds), post-generation (PII detection, groundedness enforcement).
- Agentic RAG — query planning, iterative retrieval, self-critique via DAG execution.
- Citation tracker — per-sentence source attribution with hallucination detection and groundedness scoring.
- RAG evaluation harness — faithfulness, relevance, context precision/recall, groundedness metrics.
- Hybrid retriever — vector + BM25 with Reciprocal Rank Fusion.
- Five chunking strategies — sentence, fixed-size, recursive, semantic, structure-aware.
- Seven provider connectors — OpenAI, Anthropic, Cohere, Ollama, Local TF-IDF embedder, in-memory retriever, and a plugin registry for custom providers.
Infrastructure
- ESLint auto-fixes across
src/(174 violations resolved). - Docs site published at https://devilsdev.github.io/rag-pipeline-utils/ with versioned docs.
- Dual-module build (CJS + ESM) via esbuild; TypeScript declarations auto-generated.
- 2050+ tests (unit + integration + contract) with zero production vulnerabilities at release time.
For release notes prior to v2.4.0, see github.com/DevilsDev/rag-pipeline-utils/releases.