@absolutejs/rag 0.8.0-beta.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +53 -0
- package/changelog.json +61 -0
- package/dist/adapter-kit/index.js +26 -17
- package/dist/adapter-kit/index.js.map +5 -5
- package/dist/angular/index.js +3 -3
- package/dist/angular/index.js.map +2 -2
- package/dist/client/index.js +7 -7
- package/dist/client/index.js.map +2 -2
- package/dist/client/ui.js +17 -17
- package/dist/client/ui.js.map +2 -2
- package/dist/index.js +536 -308
- package/dist/index.js.map +10 -8
- package/dist/manifest.js +127 -127
- package/dist/manifest.js.map +1 -1
- package/dist/presentation/ui.js +75 -75
- package/dist/presentation/ui.js.map +2 -2
- package/dist/quality/quality.js +130 -130
- package/dist/quality/quality.js.map +2 -2
- package/dist/react/index.js +15 -15
- package/dist/react/index.js.map +2 -2
- package/dist/src/angular/ai-rag-stream.service.d.ts +1 -0
- package/dist/src/angular/ai-rag-workflow.service.d.ts +1 -0
- package/dist/src/client/createRAGAnswerWorkflow.d.ts +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/ingestion/originalText.d.ts +29 -0
- package/dist/src/react/useRAG.d.ts +2 -0
- package/dist/src/react/useRAGStream.d.ts +1 -0
- package/dist/src/react/useRAGWorkflow.d.ts +1 -0
- package/dist/src/retrieval/originalTextTools.d.ts +23 -0
- package/dist/src/svelte/createRAG.d.ts +2 -0
- package/dist/src/svelte/createRAGStream.d.ts +1 -0
- package/dist/src/svelte/createRAGWorkflow.d.ts +1 -0
- package/dist/src/vue/useRAG.d.ts +2 -0
- package/dist/src/vue/useRAGStream.d.ts +1 -0
- package/dist/src/vue/useRAGWorkflow.d.ts +1 -0
- package/dist/svelte/index.js +15 -15
- package/dist/svelte/index.js.map +2 -2
- package/dist/vue/index.js +15 -15
- package/dist/vue/index.js.map +2 -2
- package/package.json +15 -10
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@absolutejs/rag`.
|
|
4
|
+
|
|
5
|
+
This file is generated by `absolute-changelog` from the entries in
|
|
6
|
+
`changelog/`. Edit an entry, not this file — and add new ones under
|
|
7
|
+
`changelog/unreleased/`.
|
|
8
|
+
|
|
9
|
+
## 0.9.0 — 2026-09-16
|
|
10
|
+
|
|
11
|
+
### Breaking
|
|
12
|
+
|
|
13
|
+
- **Reject unsupported lexical and hybrid retrieval instead of silently omitting keyword results; preserve requested channels for scoped heuristic queries** (`createRAGCollection`, `createHeuristicRAGRetrievalStrategy`)
|
|
14
|
+
_Migration:_ Use a store implementing queryLexical for lexical/hybrid retrieval, or explicitly select vector mode on vector-only stores. Scoped heuristic queries now retain the requested channels; update trace consumers from Scoped direct route to Scoped retrieval route.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **Allow servers to request a smaller original-source search result set while preserving candidate ranking, authorization, and exact token budgeting** (`createRAGOriginalTextTools`)
|
|
19
|
+
- **Add verbatim versioned text ingestion and authorized hybrid source tools with caller-supplied model token budgets; preserve multilingual keyword matches** (`chunkRAGOriginalText`, `readRAGOriginalText`, `createRAGOriginalTextTools`)
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **Forward AI context policy through RAG WebSocket and SSE chat; accept the next AI 0.1 release while retaining compatibility with the prior AI peer range** (`ragChat`, `createRAGWorkflow`, `useRAG`, `useRAGWorkflow`, `useRAGStream`, `createRAG`, `RAGWorkflowService`, `RAGStreamService`)
|
|
24
|
+
- **Count a complete authorized source-result envelope once when it fits, avoiding serial tokenizer round trips while retaining exact budget validation and oversized-result packing** (`createRAGOriginalTextTools`)
|
package/README.md
CHANGED
|
@@ -41,6 +41,19 @@ const results = await searchDocuments(collection, {
|
|
|
41
41
|
|
|
42
42
|
The built-in memory store supports development and tests. Published adapters provide PostgreSQL with pgvector, SQLite with optional vec0 acceleration, and Pinecone behind the same `RAGVectorStore` contract. Lexical and vector results can be fused, transformed, and reranked with provider or heuristic rerankers.
|
|
43
43
|
|
|
44
|
+
### Retrieval channel requirements
|
|
45
|
+
|
|
46
|
+
Lexical and hybrid retrieval require a store implementing `queryLexical`.
|
|
47
|
+
A backend without that capability raises an actionable error before vector
|
|
48
|
+
embedding/search instead of silently returning vector-only or empty results.
|
|
49
|
+
Explicit vector retrieval remains supported on vector-only backends. Configure
|
|
50
|
+
a lexical-capable adapter before requesting hybrid retrieval; a mode flag does
|
|
51
|
+
not add a missing backend capability.
|
|
52
|
+
|
|
53
|
+
The built-in heuristic strategy preserves the requested retrieval mode when a
|
|
54
|
+
query is scoped by source or document ID. Scope narrows the searchable corpus;
|
|
55
|
+
it does not remove the need for exact keyword matches within that corpus.
|
|
56
|
+
|
|
44
57
|
## Ingestion and source sync
|
|
45
58
|
|
|
46
59
|
The ingestion pipeline handles files, directories, uploads, URLs, PDFs, office documents, archives, images, and media transcripts. Scheduled connectors can keep collections synchronized from email, GitHub, sitemaps, feeds, directories, and S3-compatible storage.
|
|
@@ -57,3 +70,43 @@ The ingestion pipeline handles files, directories, uploads, URLs, PDFs, office d
|
|
|
57
70
|
- `@absolutejs/rag/ui` exposes presentation-neutral UI contracts.
|
|
58
71
|
|
|
59
72
|
Pair the retrieval runtime with `@absolutejs/ai` when retrieved context should feed a model or streaming assistant.
|
|
73
|
+
|
|
74
|
+
### Verbatim original text evidence
|
|
75
|
+
|
|
76
|
+
Use `chunkRAGOriginalText({ sourceId, version, text }, options)` when citations
|
|
77
|
+
must resolve against an immutable text original. This opt-in path preserves
|
|
78
|
+
whitespace and Unicode instead of normalizing or extracting document formats.
|
|
79
|
+
Each chunk includes `metadata.sourceLocator` with the source ID, immutable
|
|
80
|
+
version and UTF-16 `start`/`end` offsets. `readRAGOriginalText` validates identity,
|
|
81
|
+
version and range before returning the exact original slice. Store and authorize
|
|
82
|
+
the original separately; a locator is not an access grant.
|
|
83
|
+
|
|
84
|
+
`createRAGOriginalTextTools({ collection, filter, loadSource, budget })` provides
|
|
85
|
+
`search_text_source` and `read_text_source` AI tools. It requests real hybrid
|
|
86
|
+
retrieval with diversity and verifies evidence against originals. `filter` is a
|
|
87
|
+
server-owned scope; `loadSource(id, version)` must reauthorize every read and
|
|
88
|
+
return `null` for inaccessible/deleted versions. The tools require
|
|
89
|
+
`budget: { maxTokens, countTokens }` using the model tokenizer and a budget
|
|
90
|
+
reserved by the AI context policy. Whole passages are selected within that
|
|
91
|
+
budget; omitted passages are flagged rather than silently truncated. Add the
|
|
92
|
+
final tools/instructions before budgeting the model request. Search traces are
|
|
93
|
+
available through `onTrace`; they contain retrieval metadata and should not be
|
|
94
|
+
copied wholesale into public logs. Servers may set `searchTopK` to an integer
|
|
95
|
+
from 1 to 48 (default 12) for a smaller initial evidence lookup. Candidate ranking
|
|
96
|
+
still considers up to 48 matches; authorization and token-budget checks are
|
|
97
|
+
unchanged. A small initial result set does not establish that other facts are
|
|
98
|
+
absent: retain broader search/read tools for missing or ambiguous evidence.
|
|
99
|
+
|
|
100
|
+
Keyword matching uses Unicode word segmentation and canonical normalization.
|
|
101
|
+
English suffix rules only apply to ASCII words. This improves multilingual exact
|
|
102
|
+
matches; it does not replace evaluation of the selected embedding model.
|
|
103
|
+
|
|
104
|
+
#### AI context policy compatibility
|
|
105
|
+
|
|
106
|
+
With the AI 0.1 context-policy release, RAG chat validates the final assembled
|
|
107
|
+
retrieval context before every model request. Its `contextPolicy` config is
|
|
108
|
+
forwarded to both WebSocket and SSE generation. Use a working token target or a
|
|
109
|
+
saved-source recovery callback when appropriate. Providers without capacity
|
|
110
|
+
support require an explicit `contextPolicy: false` raw opt-out. Older supported
|
|
111
|
+
AI peers retain their previous behavior; upgrading RAG alone does not add the AI
|
|
112
|
+
0.1 capacity policy. No model-capacity numbers are defined in RAG.
|
package/changelog.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contract": 1,
|
|
3
|
+
"name": "@absolutejs/rag",
|
|
4
|
+
"releases": [
|
|
5
|
+
{
|
|
6
|
+
"changes": [
|
|
7
|
+
{
|
|
8
|
+
"kind": "changed",
|
|
9
|
+
"summary": "Forward AI context policy through RAG WebSocket and SSE chat; accept the next AI 0.1 release while retaining compatibility with the prior AI peer range",
|
|
10
|
+
"symbols": [
|
|
11
|
+
"ragChat",
|
|
12
|
+
"createRAGWorkflow",
|
|
13
|
+
"useRAG",
|
|
14
|
+
"useRAGWorkflow",
|
|
15
|
+
"useRAGStream",
|
|
16
|
+
"createRAG",
|
|
17
|
+
"RAGWorkflowService",
|
|
18
|
+
"RAGStreamService"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"kind": "added",
|
|
23
|
+
"summary": "Allow servers to request a smaller original-source search result set while preserving candidate ranking, authorization, and exact token budgeting",
|
|
24
|
+
"symbols": [
|
|
25
|
+
"createRAGOriginalTextTools"
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"kind": "changed",
|
|
30
|
+
"summary": "Count a complete authorized source-result envelope once when it fits, avoiding serial tokenizer round trips while retaining exact budget validation and oversized-result packing",
|
|
31
|
+
"symbols": [
|
|
32
|
+
"createRAGOriginalTextTools"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"kind": "added",
|
|
37
|
+
"summary": "Add verbatim versioned text ingestion and authorized hybrid source tools with caller-supplied model token budgets; preserve multilingual keyword matches",
|
|
38
|
+
"symbols": [
|
|
39
|
+
"chunkRAGOriginalText",
|
|
40
|
+
"readRAGOriginalText",
|
|
41
|
+
"createRAGOriginalTextTools"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"kind": "breaking",
|
|
46
|
+
"migration": {
|
|
47
|
+
"instruction": "Use a store implementing queryLexical for lexical/hybrid retrieval, or explicitly select vector mode on vector-only stores. Scoped heuristic queries now retain the requested channels; update trace consumers from Scoped direct route to Scoped retrieval route.",
|
|
48
|
+
"manual": true
|
|
49
|
+
},
|
|
50
|
+
"summary": "Reject unsupported lexical and hybrid retrieval instead of silently omitting keyword results; preserve requested channels for scoped heuristic queries",
|
|
51
|
+
"symbols": [
|
|
52
|
+
"createRAGCollection",
|
|
53
|
+
"createHeuristicRAGRetrievalStrategy"
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"date": "2026-09-16",
|
|
58
|
+
"version": "0.9.0"
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
@@ -11437,7 +11437,8 @@ var STOP_WORDS = new Set([
|
|
|
11437
11437
|
"which",
|
|
11438
11438
|
"why"
|
|
11439
11439
|
]);
|
|
11440
|
-
var
|
|
11440
|
+
var wordSegmenter = new Intl.Segmenter("und", { granularity: "word" });
|
|
11441
|
+
var tokenize = (value) => value.normalize("NFC").toLowerCase().split(/[^\p{L}\p{M}\p{N}]+/u).flatMap((part) => /^[a-z0-9]+$/.test(part) ? [part] : [...wordSegmenter.segment(part)].filter((segment) => segment.isWordLike).map((segment) => segment.segment)).map((token) => token.trim()).filter((token) => !STOP_WORDS.has(token)).map((token) => !/^[a-z]+$/.test(token) ? token : token.endsWith("ies") && token.length > 3 ? `${token.slice(0, -3)}y` : token.endsWith("ing") && token.length > 5 ? token.slice(0, -3) : token.endsWith("ed") && token.length > 4 ? token.slice(0, -2) : token.endsWith("es") && token.length > 4 ? token.slice(0, -2) : token.endsWith("s") && token.length > 3 ? token.slice(0, -1) : token).filter((token) => token.length > 1 || /[^a-z]/.test(token));
|
|
11441
11442
|
var BM25_K1 = 1.2;
|
|
11442
11443
|
var BM25_B = 0.75;
|
|
11443
11444
|
var collectMetadataStrings = (value) => {
|
|
@@ -11454,7 +11455,7 @@ var collectMetadataStrings = (value) => {
|
|
|
11454
11455
|
};
|
|
11455
11456
|
var normalizeSourceForLexical = (source) => source.replace(/[#/_.-]+/g, " ").replace(/\bmd\b/g, "markdown").replace(/\bpptx\b/g, "presentation").replace(/\bxlsx\b/g, "spreadsheet workbook sheet").replace(/\bmp3\b/g, "audio transcript media").replace(/\bmp4\b/g, "video transcript media").replace(/\bzip\b/g, "archive bundle");
|
|
11456
11457
|
var toFieldText = (value) => collectMetadataStrings(value).filter(Boolean).join(" ");
|
|
11457
|
-
var normalizeLooseText = (value) => value.toLowerCase().replace(/[
|
|
11458
|
+
var normalizeLooseText = (value) => value.normalize("NFC").toLowerCase().replace(/[^\p{L}\p{M}\p{N}]+/gu, " ").trim().replace(/\s+/g, " ");
|
|
11458
11459
|
var scoreLoosePhraseMatch = (query, text) => {
|
|
11459
11460
|
const normalizedQuery = normalizeLooseText(query);
|
|
11460
11461
|
const normalizedText = normalizeLooseText(text ?? "");
|
|
@@ -20788,7 +20789,13 @@ var annotateRetrievalQueryOrigin = (input) => {
|
|
|
20788
20789
|
}));
|
|
20789
20790
|
};
|
|
20790
20791
|
var shouldRunVectorRetrieval = (mode) => mode === "vector" || mode === "hybrid";
|
|
20791
|
-
var shouldRunLexicalRetrieval = (mode, store) =>
|
|
20792
|
+
var shouldRunLexicalRetrieval = (mode, store) => {
|
|
20793
|
+
if (mode === "vector")
|
|
20794
|
+
return false;
|
|
20795
|
+
if (!store.queryLexical)
|
|
20796
|
+
throw new Error(`Retrieval mode "${mode}" requires a store with queryLexical. Configure a lexical-capable adapter or explicitly request vector retrieval.`);
|
|
20797
|
+
return true;
|
|
20798
|
+
};
|
|
20792
20799
|
var resolveRAGRetrievalStrategy = (retrievalStrategy) => {
|
|
20793
20800
|
if (!retrievalStrategy) {
|
|
20794
20801
|
return null;
|
|
@@ -23115,6 +23122,7 @@ var ragChat = (config) => {
|
|
|
23115
23122
|
handleRAGRetrieved(ws, conversationId, assistantMessageId, sources, retrievalStartedAt, retrievedAt, retrievalDurationMs, trace);
|
|
23116
23123
|
await streamAI(ws, conversationId, assistantMessageId, {
|
|
23117
23124
|
completeMeta: includeCompleteSources ? { sources } : undefined,
|
|
23125
|
+
contextPolicy: config.contextPolicy,
|
|
23118
23126
|
maxTurns: config.maxTurns,
|
|
23119
23127
|
messages: [
|
|
23120
23128
|
...history,
|
|
@@ -29891,6 +29899,7 @@ var ragChat = (config) => {
|
|
|
29891
29899
|
const messageWithContext = buildUserMessage(content, lastMessage.attachments, ragContext);
|
|
29892
29900
|
const sseStream = streamAIToSSE(conversationId, assistantMessageId, {
|
|
29893
29901
|
completeMeta: includeCompleteSources ? { sources } : undefined,
|
|
29902
|
+
contextPolicy: config.contextPolicy,
|
|
29894
29903
|
maxTurns: config.maxTurns,
|
|
29895
29904
|
messages: [...userHistory, messageWithContext],
|
|
29896
29905
|
model,
|
|
@@ -31389,21 +31398,21 @@ var RAG_NATIVE_QUERY_CANDIDATE_LIMIT = 1000;
|
|
|
31389
31398
|
var RAG_VECTOR_DIMENSIONS_DEFAULT = 24;
|
|
31390
31399
|
var TWO_THIRDS = 2 / 3;
|
|
31391
31400
|
export {
|
|
31392
|
-
|
|
31393
|
-
resolveAdaptiveNativeCandidateLimit,
|
|
31394
|
-
rankRAGLexicalMatches,
|
|
31395
|
-
ragChat as ragPlugin,
|
|
31396
|
-
ragChat,
|
|
31397
|
-
querySimilarity,
|
|
31398
|
-
planNativeCandidateSearchK,
|
|
31399
|
-
planNativeCandidateSearchBackfillK,
|
|
31400
|
-
normalizeVector,
|
|
31401
|
-
matchesMetadataFilterRecord,
|
|
31402
|
-
createRAGVector,
|
|
31403
|
-
createRAGCollection,
|
|
31401
|
+
RAG_NATIVE_QUERY_CANDIDATE_LIMIT,
|
|
31404
31402
|
RAG_VECTOR_DIMENSIONS_DEFAULT,
|
|
31405
|
-
|
|
31403
|
+
createRAGCollection,
|
|
31404
|
+
createRAGVector,
|
|
31405
|
+
matchesMetadataFilterRecord,
|
|
31406
|
+
normalizeVector,
|
|
31407
|
+
planNativeCandidateSearchBackfillK,
|
|
31408
|
+
planNativeCandidateSearchK,
|
|
31409
|
+
querySimilarity,
|
|
31410
|
+
ragChat,
|
|
31411
|
+
ragChat as ragPlugin,
|
|
31412
|
+
rankRAGLexicalMatches,
|
|
31413
|
+
resolveAdaptiveNativeCandidateLimit,
|
|
31414
|
+
summarizeSQLiteCandidateCoverage
|
|
31406
31415
|
};
|
|
31407
31416
|
|
|
31408
|
-
//# debugId=
|
|
31417
|
+
//# debugId=5D1CC4781115DD5864756E2164756E21
|
|
31409
31418
|
//# sourceMappingURL=index.js.map
|