Mythosia.AI.Rag - Release Notes
v8.3.0
Changed
- Chunk lookup, all-record query scoring and diagnostic health checks detect optional
Mythosia.VectorDb.IVectorStoreDiagnostics. The same diagnostic paths work with standalone InMemory 4.3.0 and compatible custom diagnostic stores.
Compatibility
- Legacy custom stores retain their original interface dispatch through an internal adapter, including stores with public diagnostic helpers alongside explicit
IRagDiagnosticsStoremethods. - Intentional breaking change in a minor release: As a one-time versioning-policy exception, this release includes
Mythosia.VectorDb.InMemory4.3.0, which no longer implementsIRagDiagnosticsStore. Change assignments, casts and capability checks on InMemory toIVectorStoreDiagnostics; the concrete diagnostic methods remain available. - Requires
Mythosia.AI.Abstractions4.2.0 andMythosia.AI.Rag.Abstractions6.5.0. Legacy custom stores implementingIRagDiagnosticsStorecontinue through its compatibility bridge. The legacy type remains in its original assembly and namespace. - Normal RAG indexing and retrieval still use
IVectorStore; stores without the diagnostics capability remain supported. Limited query diagnostics and existing unsupported-operation behavior are retained for those stores. - This interface migration does not change stored records or require reindexing. Upgrade RAG together with InMemory to retain full diagnostics.
v8.2.0
Added
VoyageContextualizedEmbeddingProvidersupportsvoyage-context-4, default 1024 dimensions. RAG passes each complete ordered document as one contextual group, independently of the generic embedding batch size. Document and query calls use their respective retrieval input types, without mixing document contexts or silently splitting or truncating an oversized document.GeminiEmbeddingProvidersupports text withgemini-embedding-2, default 1536 dimensions. Each chunk produces an independent vector, with bounded concurrent HTTP requests. Official document-title/text and search-query prefixes are applied only to API inputs; indexed source text remains unchanged. Automatic truncation is disabled.RagBuilder.UseVoyageEmbeddingandUseGeminiEmbeddingconfigure caller-owned HTTP clients, model IDs, dimensions and optional timeouts. Voyage applies its timeout per HTTP request; Gemini applies it to the whole embedding operation, including concurrency waits. Providers validate response shape, input/result association, counts, dimensions and finite values while allowing unused response fields. HTTP errors exclude response bodies and credentials; cancellation reaches request and body transfer.
Changed
- Indexing, vector/hybrid retrieval, legacy strategy adapters and diagnostics detect optional
IRetrievalEmbeddingProvider. Indexing suppliesEmbeddingDocumentwith snapshotted identity, title and ordered chunk text; query paths use the explicit query method. Keyword-only retrieval still avoids embedding calls. PerplexityContextualizedEmbeddingProviderimplements the same optional contract. Its existing grouped API and binary APIs remain available. Generic flat embedding methods treat texts as independent groups.- Voyage generic batches check cancellation while reading inputs and stop as soon as the 1,000-text limit is exceeded, rejecting the batch before any HTTP request. Complete document groups remain intact.
- Perplexity standard and contextualized float/binary methods check cancellation while reading inputs and stop at the first exceeded count limit before sending HTTP. Standard batches allow 512 texts; contextual batches allow 512 documents and 16,000 total chunks. Document grouping, chunk order and existing public signatures are preserved.
Compatibility
- Existing
IEmbeddingProvidersignatures and implementations are unchanged and retain generic batching. RequiresMythosia.AI.Rag.Abstractions6.4.0. No other package upgrade is required by this release. - Switching embedding models, dimensions or document/query formatting requires re-embedding affected documents in an appropriate vector collection, even when vector dimensions match. Merely upgrading with an existing provider does not require reindexing.
- All vectors for one document are validated before its replacement begins. HTTP failures and cancellation during embedding leave that document's stored vectors unchanged; persistence rollback guarantees continue to depend on the vector store's replacement implementation.
Internal
- Added provider and integration regressions for document grouping beyond the default batch size, separate documents, reordered/malformed responses, buffer ownership, original text preservation, cancellation and timeout/error handling.
- Added opt-in live TXT/Markdown/PDF extraction, indexing and retrieval checks for both providers, including a 101-chunk Voyage document. The strict runner rejects skipped or inconclusive results; live validation requires provider credentials and incurs API charges.
v8.1.1
Changed
- Existing
RagEnabledServicewrappers now honorRagStore.SetQueryRewriteradditions, replacement and clearing. Each request captures the current rewriter once after initialization; requests already using a rewriter retain that instance and its search decision, rewritten query and keywords. Later requests use the new setting, matching the history-taking direct store overloads. - Lazy initialization configures the automatic rewriter before publishing the store to concurrent requests. A custom rewriter is preserved, the automatic default is created only once, and explicitly clearing it does not recreate it on a later request.
Internal
- Added 11 regression cases covering existing shared wrappers, replacement, clearing, in-flight requests and custom/automatic lazy defaults. The complete RAG test suite passes all 938 tests without external LLM API calls.
Compatibility
- No public API changes, index migration or reindexing are required when upgrading from 8.1.0. Dependency requirements remain unchanged; use
Mythosia.AI8.1.0 for the current provider integrations. - Earlier document-identity and chunk-boundary migration guidance in the 8.1.0 notes still applies when upgrading affected indexes from older versions.
v8.1.0
Added
RagEnabledService.WithSpeed(InferenceSpeed)configures provider processing for the next generated answer after retrieval.LastProcessingand RunProcessingreport that answer without mixing in internal query rewriting. The supporting provider decides allowed modes; Fast can incur premium charges and unsupported modes fail explicitly. Existing retrieval and embedding modes are unchanged. See processing speed.- Optional
Mythosia.AI.Rag.Search.Pixie0.1.0-preview can connect through.UseStore(new PixieInMemoryStore(encoder))with the current dense embedding provider, keyword/vector modes and configurable hybrid retrieval. Its learned sparse index is local and memory-only; existing RAG defaults are unchanged. See the PIXIE guide. - Request-based retrieval via
IRagRetriever, builderUseRetriever, pipelineSetRetriever, and storeUpdateRetriever; custom retrievers receive query text, top-K, filters, progress and cancellation without a mandatory embedding. UseKeywordSearchandHybridSearchOptionsoverloads select text retrieval or explicitly configured weighted RRF. RuntimeRagStore.UseKeywordSearch()andUpdateRetrievalStrategy(HybridSearchOptions)are available.
Changed
- Query preparation belongs to the retriever; document ingestion continues to create dense embeddings. Standard and Agentic RAG share retrieval configuration, and a missing lexical override uses the full query in built-in text/hybrid retrieval.
- Unsupported search modes/settings now fail explicitly. Existing
IRetrievalStrategyretains dense-input behavior through an adapter; default Pinecone native hybrid remains supported. New configurable hybrid results consistently use normalized weighted RRF, including single active legs. No analyzer or existing-index migration is included.
Fixed
Respect Ada embedding dimensions:
OpenAIEmbeddingProvideromits the unsupporteddimensionsfield fortext-embedding-ada-002in single/batch requests and rejects configured dimensions other than its fixed 1536 withArgumentOutOfRangeExceptionbefore any API call.text-embedding-3-smallandtext-embedding-3-largecontinue sending their configured dimensions. Public signatures, defaults and model availability are unchanged.Preserve tool results in RAG completion: The core request-message override stays attached to the initial input of a logical request instead of replacing the newest message after each tool round. Ordinary RAG
GetCompletionAsyncrequests keep retrieved context, assistant tool calls and tool outputs together, including image-bearing inputs. Original history and public APIs are unchanged.Preserve RAG message attachments:
RagEnabledService.GetCompletionAsync(Message)now retains non-text attachments in the augmented request, matchingStartRunAsync(Message). Retrieval continues to use message text, and retrieved context does not overwrite the original message or the user text stored in conversation history. Media support remains provider/model-specific.Keep query rewriting stable during runtime changes: The direct
RagStore.QueryAsyncoverload acceptingconversationHistorycaptures the selected rewriter before awaiting progress or rewriting. Disabling or replacing it throughSetQueryRewriterno longer causes an in-flight query to dereference a cleared rewriter or switch implementations; subsequent queries use the new setting. Public signatures are unchanged.Validate compressed URL documents before replacing content:
AddUrldecodes gzip, zlib-wrapped deflate and Brotli, checks compression completion and available format checksums, and rejects unsupported or nested content encodings before embedding or persistence. A successful HTTP transfer with a truncated compression stream no longer replaces the document with partial text. Retains download/decode cancellation and charset/BOM handling. Uses SharpZipLib 1.4.2 for managed DEFLATE decoding and checksums, plus the standard Brotli decoder; no process-wide compression settings change. Reindex any previously corrupted URL documents from their original source.Request Ollama embedding dimensions:
/api/embedrequests now include the configureddimensions, so the defaultqwen3-embedding:4bprovider requests 1024 dimensions instead of expecting 1024 from an unconfigured 2560-dimensional response. Constructor defaults and signatures are unchanged. The model/server must support the selected dimension; HTTP errors and mismatched responses remain failures, with no silent resizing or fallback. Rebuild existing indexes when changing embedding models or dimensions.Stable Office/PDF document identity: Word, Excel, PowerPoint and PDF file loaders use normalized absolute paths as
Source, matching TXT loading. Relative and absolute registrations derive the same automatic ID. Existing relative-path records need explicit deletion by their old document ID before reindexing, or indexing the complete source set into a new empty collection and switching after validation; reindexing only the new ID in the existing collection does not remove old records. Unrelated records and explicit IDs must be preserved.Validate and capture query vectors: Built-in dense query retrieval and the legacy strategy adapter validate positive dimensions, exact length and finite values, then immediately copy the returned vector before progress callbacks or search can await. Invalid provider output fails before search; custom retrievers retain responsibility for their own query preparation.
Validate Ollama embedding responses: Direct single/batch calls reject malformed response shape, vector counts, dimensions and non-finite values with
InvalidOperationException. SuppliedHttpClientownership remains with the caller.Cancel URL document loading:
AddUrlforwards indexing/build cancellation into the HTTP request and response-body reading rather than waiting for the download to finish. Cancellation does not roll back previously completed document writes.Document-scoped callback examples: Official persistence callbacks replace records by normalized
document_idinstead of only upserting new chunks, so shorter updates remove old tails. Empty split results still skip the callback and require explicit deletion of the known document ID in custom storage. Atomicity and rollback remain storage-specific.Validate indexing before persistence: Missing or whitespace-only document IDs fail with
ArgumentException; malformed splitter output, missing or duplicate chunk IDs within a document fail withInvalidOperationExceptionbefore embeddings, storage or the persistence callback. Valid custom IDs are preserved, and chunk values/metadata are copied before the first embedding request. Global custom-ID collisions across documents are not automatically detected.Validate embedding batches: Require a positive dimension, exactly one non-null vector per input, matching lengths and finite values before persistence; copy each batch's vectors before requesting the next batch. Validation failures preserve the affected document's previous records and skip custom persistence. OpenAI response indices are required, checked and reordered; vLLM retains fully index-free response compatibility while rejecting partially missing or invalid indices. These checks and response-order corrections do not automatically recover previously overwritten content or incorrectly paired stored vectors; reindex affected documents from their original sources.
Custom splitter examples: All 13 documentation languages now assign unique document-based chunk IDs and inherit document metadata, preserving filters and preventing silent overwrites caused by omitted IDs.
Recursive separator allocation: Avoid repeatedly copying an unchanged segment when distinct separators only match its beginning. Existing chunk output is preserved while large separator configurations allocate substantially less memory.
Bounded Markdown context: Repeated headings, table headers and prose labels count toward a per-document output budget of
max(65536, 32 ร document.Content.Length)UTF-16 code units. Excessive expansion fails withInvalidOperationExceptionbefore constructing it, without silently truncating content or returning partial chunks. Default RAG indexing preserves existing records when splitting fails.Paragraph-aware labels: Bold text on a soft-wrapped line inside an existing paragraph is no longer promoted to a label, repeated across chunks or separated by an inserted blank line. Labels require a paragraph or structural boundary.
Recursive separator settings: Duplicate separators are applied once in first-occurrence order, and an explicit work stack replaces nested recursive calls so long settings do not multiply repeated passes or consume the call stack.
Reserved document identity: Stored records and custom persistence callbacks receive copied metadata with
document_idnormalized to the actualRagDocument.Id. Conflicting caller metadata cannot redirect the document replacement filter; input document and splitter dictionaries remain untouched. Previously mis-tagged records are not repaired automatically: rebuild from trusted sources or perform scoped cleanup before reindexing.Stable embedding batches: Document indexing validates that
EmbeddingBatchSizeis positive and captures it for the call before embedding or replacement. Invalid sizes cannot loop over empty batches, and changes during an awaited operation do not skip chunks.Markdown semantic isolation: Only standalone bold prose labels repeat within their text block; tables, fences, headings and subsequent labels end that scope. Bold table cells are not repeated as conditions for other rows or later prose. Opening-fence indentation is preserved with the code, and opening-fence metadata is parsed once per block, removing repeated scans for pathological long fences.
TXT/Markdown chunk correctness: Character, Recursive and Token splitters reject invalid sizes and negative overlap rather than hanging or skipping text. Recursive merging respects the size budget and zero-overlap setting; Character/Token no longer append an overlap-only tail. Character, Recursive and Markdown avoid cutting UTF-16 surrogate pairs (a pair may exceed a size of one).
Markdown content and structure: Disabling heading breadcrumbs preserves original headings, heading-only content is retained, fence closure respects the opening character and length, and GFM table recognition supports optional outer pipes. A parent-heading change closes the preceding child section so its old breadcrumb is not attached to new content, including when
MinSplitHeadingLevelskips that parent level. Ordinary content uses the requested budget without an implicit minimum; complete fenced blocks and a table header plus one row may exceed it. Repeated heading breadcrumbs remain outside the content budget.Splitter guidance: Corrected Markdown constructor examples across all 13 documentation languages, clarified that
TokenTextSplittercounts whitespace-separated units rather than model tokens, and documented validation, overlap and atomic-block limits. Reindex affected documents and refresh evaluation inputs/caches after chunk-boundary changes; existing stored chunks are not automatically updated. No public method signatures or default splitter selection change.Isolate LLM reranking requests:
LlmRerankernow applies request-scoped stateless execution so a shared AI service does not include earlier document assessments, existing conversation history, or stored summaries of earlier conversations in later scoring requests. Evaluation prompts and responses are not added to history; service defaults and caller APIs are unchanged. Evaluations by rerankers sharing the same AI service are processed sequentially.Separate same-named files across directories:
PlainTextDocumentLoaderandDirectoryDocumentLoaderuse normalized absolute file paths asSourceand automatic document IDs. Equivalent relative/absolute paths reuse an ID; distinct directory roots no longer overwrite each other. ExplicitAddTextIDs,RagDocument.Id, custom loader rules and caller APIs are unchanged. Default directoryfilename/relative_pathmetadata remains available for display. Existing relative-path IDs are not automatically migrated or deleted, and default citations may now show absolute paths. See document identity and index migration.Clear stale content after an empty update: When splitting succeeds with zero chunks, default persistence replaces records for that
document_idwith an empty set. It skips embeddings, preserves other document IDs and allows later nonempty updates under the same ID. Exceptions before storage and cancellation observed before the storage call preserve that document's records; rollback after storage starts remains store-specific. Empty loader results are not deletion instructions, andonDocumentEmbeddedkeeps its existing zero-chunk behavior (no callback or default-store access). Public APIs are unchanged. See empty document updates.
Compatibility
- Requires
Mythosia.AI.Abstractions4.1.0,Mythosia.AI.Rag.Abstractions6.3.0,Mythosia.VectorDb.InMemory4.2.0,Mythosia.Documents.Office1.1.1 andMythosia.Documents.Pdf1.1.2. Existing public retrieval APIs remain available; useMythosia.AI8.1.0 for the current provider integrations. - Corrected chunk boundaries and document identities do not rewrite existing indexes. Apply the scoped cleanup and reindexing guidance above when upgrading an affected index.
v8.0.0
This coordinated major release changes public contracts. See the v8 migration guide before upgrading the package family.
Added
Forwards the major
AIRun.Resultchange toTask<AIRunResult>through the existing RAG Run wrapper. Callers read.Textfor the answer or inspect the inner execution's reported usage, citations, model, rounds, and finish details without a stream reader. Retrieval/embedding usage is not added to model token usage. RAG completion remainsTask<string>and the package remains independent of the full core implementation. See migration.Ordinary completion cancellation: RAG completion overloads propagate the caller token through retrieval, query rewriting and the inner completion call. Cancellation skips the subsequent model request when retrieval is cancelled. The wrapper implements the updated
IAIServicesignatures without depending on the full core implementation. Cooperative retrieval and tool cleanup retain the common cancellation limits. See the common contract.WithAgenticRagforwards the execution cancellation token intoRagStore.QueryAsync. Search failures remain available in diagnostic traces and propagate to the common executor as failed tool results; they no longer return successful error strings. Cancellation remains cooperative in retrieval components.Perplexity standard 0.6B/4B embedding providers for ordinary RAG retrieval, with a
UsePerplexityEmbeddingbuilder extension. Signed int8 vectors are decoded and normalized for the existing float-vector interface.Separate contextualized 0.6B/4B embedding APIs retain each document's ordered chunks instead of flattening unrelated documents. Packed binary embeddings use an explicit result type and Hamming distance; they are not silently converted into float embeddings. See the Perplexity guide.
Internal
- Rebuilt against
Mythosia.AI.Abstractionsv4.0.0 for the coordinated major release, including updated completion cancellation and rich Run-result contracts. RAG request-feature scopes let a supporting inner service retain captured provider options while retrieval and query rewriting run.
Compatibility
- Existing retrieval APIs remain available; the Perplexity embedding APIs are additions. Contextualized embeddings do not implement the flat
IEmbeddingProvidercontract. RequiresMythosia.AI.Abstractionsv4.0.0+ andMythosia.AI.Rag.Abstractionsv6.2.0+. - RAG still depends on the lightweight contracts and does not acquire a dependency on the full core implementation.
v7.6.0
Added
- Control a RAG answer with Run:
RagEnabledService.StartRunAsyncretrieves documents once, forwards the augmented request to the inner service, and returns the sameAIRunfor text callbacks, output events, the collected result, cancellation, and supported steering. Message content and request context are preserved. Steering does not repeat the initial retrieval. - Reasoning and hosted search:
WithReasoning,WithWebSearch, andWithFileSearchconfigure the final answer, including completion, structured-output repair, and Run paths. Provider sources are available throughLastCitationsand the returned run; RAG retrieval references remain onRagProcessedQuery. - Agentic RAG with Run: existing
WithAgenticRagtools work withStartRunAsyncand the configured function-round policy when additional model-directed searches are needed.
Changed
- Request features are captured before retrieval and consumed for one logical request. Internal query rewriting does not inherit final-answer search settings; retrieval and validation failures do not leak pending options to the next request.
- NuGet packages now include these full release notes and symbol packages, with repository and license metadata.
Fixed
- Duplicate-source filtering: when every input document path has already been processed,
RagBuildernow returns an empty list. Overlapping file and directory registration no longer re-embeds those documents or changes their splitter selection through a later registration.
Compatibility
- Requires
Mythosia.AI.Abstractionsv3.1.0+ andMythosia.AI.Rag.Abstractionsv6.2.0+. The package continues to depend on the lightweight AI contracts, not the fullMythosia.AIimplementation. - Existing completion and streaming APIs remain callable. Run requires an inner service implementing optional
IAIRunService; common request features requireIAIRequestFeatureService. Unsupported capabilities fail explicitly. - See the Run guide and reasoning/search guide for provider support and migration examples.
v7.5.0
Fixed
RagPipeline.QueryAsync(query, topK, filter, ct)silently droppedProgressAsyncandStoreFilterโ the convenience overload manually rebuiltRagQueryOptionsfromOptions.DefaultQuerybut only copiedFinalFilter,RetrievalDerivation, andFinalSelection. Any tenant/permission scope set onDefaultQuery.StoreFilterand any progress callback onDefaultQuery.ProgressAsyncwere lost whenever a caller used thetopK-only overload. The overload now usesRagQueryOptions.Clone()(introduced inMythosia.AI.Rag.Abstractionsv6.2.0) and overrides onlyFinalFilter.TopK, preserving every other configured field.Race condition on
PromptTemplatecache โRagPipelinecached the resolvedIContextBuilderagainstOptions.PromptTemplateto skip per-query allocation. WithRagStore.UpdateOptionsallowing runtime template changes while queries are in flight, two correlated fields (_cachedPromptTemplate,_resolvedContextBuilder) could tear, briefly returning the previous builder against the new template. The cache has been removed entirely โTemplateContextBuilderconstruction is a single reference assignment, dwarfed by the embedding/search I/O each query already incurs, so the cache existed for negligible benefit at the cost of a thread-safety hazard.RagStore.UpdateOptionssnapshot safety - runtime option updates now configure a clonedRagPipelineOptionsinstance and atomically swap the completed snapshot into the pipeline, so in-flight queries do not observe partially-mutated option objects.
Compatibility
- Requires
Mythosia.AI.Rag.Abstractionsv6.2.0+. - No public API changes in
Mythosia.AI.Rag. Existing callers see strictly more correct behavior โ the previously-lost fields are now honored, andPromptTemplateupdates take effect deterministically on the next query.
v7.4.0
Added
WithAgenticRag(..., queryOptions: ...)now supports per-tool-callRagQueryOptions, enabling Agentic RAG permission filters such asStoreFilter.WithAgenticRagTracing(...)+AgenticRagSearchTraceprovide structured step-level access to each Agentic RAG search query, references, candidates, diagnostics, and failures.AgenticRagQueryContextgivesqueryOptionsaccess to the current tool name and self-contained search query for dynamic per-step filtering or retrieval policy selection.
v7.3.2
Changed
- Recompiled for the
Mythosia.AIv6.1.0 release line. - No changes to
Mythosia.AI.Ragsource code, public API, or runtime behavior.
v7.3.1
MarkdownTextSplitter Improvements
- Bold label propagation โ
**label**context is now tracked and prepended to all subsequent chunks within a section, regardless of where the split occurs (MergeBlocksIntoChunksorSplitOversizedBlock). Propagation logic moved toChunkSectionsfor universal coverage. - Cascading split โ oversized text blocks are split in stages: paragraph (
\n\n) โ line (\n) โ word boundary (space), minimizing mid-word breaks. - 50-char buffer margin โ chunk budget reserves 50 characters for breadcrumb and label overhead, preventing chunk size overflow.
- Method renames โ
SplitContentBlocksโMergeBlocksIntoChunks,SplitLargeTextโSplitOversizedBlockfor clarity.
Dependency Updates
- Recompiled against
Mythosia.Documents.Office1.0.1,Mythosia.Documents.Pdf1.1.1 (both updated forMythosia.Documents.Abstractions1.1.0).
v7.3.0
Breaking Changes
RagBuilder.WithNamespace()removed.HealthCheckResult.Namespaceremoved โ constructor changed from(string @namespace, int totalChunks, items)to(int totalChunks, items).
Changed
- Internal namespace/scope handling migrated to Metadata โ follows
Mythosia.VectorDb.Abstractionsv4.0.0.RagPipeline.BuildAsyncnow writes namespace/scope toMetadata["namespace"]/Metadata["scope"]instead ofVectorRecord.Namespace/VectorRecord.Scope.RagPipeline.QueryAsyncnow applies namespace filter viaVectorFilter.Where("namespace", ns)instead ofVectorFilter.Namespace.RagPipeline.DeleteDocumentAsyncupdated similarly.HybridRetrievalStrategy.WithoutMinScoreno longer copies removedNamespace/Scopeproperties โ conditions are preserved viaAppendConditionsFrom.RagDiagnostics.DiagnoseQueryAsyncfallback filter updated.RagDiagnosticSessionerror message: "namespace/metadata" โ "metadata".HealthCheckResult.ToReport():Namespace: "default" (N chunks)โN chunks indexed.
- Default indexing now uses
ReplaceByFilterAsyncโ when noonDocumentEmbeddedcallback is provided,IndexSingleDocumentAsyncnow callsReplaceByFilterAsync(Where("document_id", docId), records)instead ofUpsertBatchAsync(records).- Fixes stale chunk problem: re-indexing a file that produces fewer chunks no longer leaves orphan chunks from the previous version.
- The operation is atomic (transactional in stores that support it) โ on failure, existing data remains intact.
onDocumentEmbeddedcallback behavior is unchanged โ when provided, it still replaces the default persistence logic entirely.
Compatibility
- Requires
Mythosia.AI.Rag.Abstractionsv6.1.0,Mythosia.VectorDb.Abstractionsv4.0.1.
v7.1.0
Added
WithAgenticRag<TService>(RagStore, string?, string?)โ new extension method onAgenticRagExtensionsthat registers theRagStoreas a callable search tool on any AI service implementing bothIAIServiceandIFunctionRegisterable.- Registers a
search_documentsfunction (name configurable viatoolName) in the agent's function list. - Inside the tool handler,
RagStore.QueryAsync(query)is called directly โQueryRewriteris intentionally bypassed. The agent formulates its own self-contained search query as part of its ReAct reasoning. - Returns all retrieved excerpts with source metadata as a formatted string for the agent to reason over.
- When no results are found, returns a descriptive fallback message so the agent can decide to retry with a different query.
- Tool description is customizable via
toolDescriptionparameter; defaults to a domain-agnostic description that instructs the agent to use self-contained queries. - Fully compatible with combining other tools via
WithFunction/WithFunctionAsync.
- Registers a
Compatibility
- Requires
Mythosia.AI.Abstractionsv1.1.0.
Usage
var ragStore = await RagStore.BuildAsync(cfg => cfg
.AddDocument("manual.pdf")
.UseOpenAIEmbedding(apiKey));
// Basic: RAG as the only tool
var service = new ClaudeService(apiKey, http);
service.WithAgenticRag(ragStore);
var answer = await service.RunAgentAsync("Summarise the refund policy.");
// Combined with other tools
service.WithAgenticRag(ragStore)
.WithFunctionAsync("get_order_status", "Look up an order by ID.",
("order_id", "The order ID.", required: true),
async id => await orderApi.GetStatusAsync(id));
// Custom tool description for better domain-specific selection
service.WithAgenticRag(ragStore,
toolDescription: "Search HR policies and product manuals.");
Design Notes
QueryRewriterset on theRagStoreis intentionally not invoked. The agent's own ReAct reasoning replaces the rewriter's role โ it produces a clean, standalone query before calling the tool.- Existing
WithRag()/RagEnabledServiceflows are completely unaffected. - Requires
Mythosia.AI.Abstractionsv1.1.0 andMythosia.AIv5.3.0 (both implementIFunctionRegisterable).
Compatibility
- No breaking changes to any existing API.
- Requires
Mythosia.AI.Abstractionsv1.1.0 forIFunctionRegisterable.
v7.0.1
Changed
- Mythosia.Documents.Pdf dependency updated to v1.1.0 โ structured extraction improvements including font-size based heading detection, bullet/numbered list recognition, and spatial paragraph grouping.
v7.0.0
Breaking Changes
VectorFilter construction API changed (see Mythosia.VectorDb.Abstractions v3.0.0). Any code that assigns RagQueryOptions.StoreFilter using the old API must be updated:
// Before โ compile error in v7.0.0
options.StoreFilter = VectorFilter.ByMetadata("storage_id", id);
options.StoreFilter = new VectorFilter { MetadataMatch = new Dictionary<string, string> { ["storage_id"] = id, ["folder"] = "/docs" } };
// After
options.StoreFilter = new VectorFilter().Where("storage_id", id);
options.StoreFilter = new VectorFilter().Where("storage_id", id).Where("folder", "/docs");
Requires Mythosia.AI.Rag.Abstractions v6.0.0, Mythosia.VectorDb.Abstractions v3.0.0, Mythosia.VectorDb.InMemory v3.0.0.
Changed
MergeStoreFilter(internal) โ rewrote filter merge logic to useAppendConditionsFromon the newVectorFiltercondition tree instead of mergingMetadataMatchdictionaries.storeFilterconditions are appended first (permission constraints), followed by per-queryfilterconditions.Scopeis taken fromstoreFilterwhen set, falling back to the query filter.DeleteDocumentAsyncโ usesnew VectorFilter().Where("document_id", documentId)instead of the removedVectorFilter.ByMetadata().HybridRetrievalStrategy.WithoutMinScoreโ updated to copy the condition tree viaAppendConditionsFrominstead of copying the removedMetadataMatchproperty.
v6.2.0
Dependency Changes
Mythosia.AIโMythosia.AI.Abstractionsโ the Rag package now depends on the lightweight abstractions package instead of the full AI implementation. All public API surface acceptsIAIService(widened fromAIServiceโ existing callers remain source-compatible).WithoutRag()now returnsIAIService.Mythosia.AI.Loaders.Office/PdfโMythosia.Documents.Office/Pdfโ follows the package rename.
Added
DoclingDocumentConverterโ convertsDoclingDocument(fromMythosia.Documents) toRagDocument(fromMythosia.AI.Rag). Used internally byRagBuilderfor all loader integrations.RagQueryOptions.StoreFilterpassthrough โVectorFilter?property onRagQueryOptionsthat is passed directly toIVectorStore.SearchAsync/IVectorStore.HybridSearchAsyncon every retrieval call.- Enables per-query tenant isolation, permission-based filtering, category scoping, and time-range filtering without wrapping the store in a custom decorator.
- When
StoreFilterisnullthe pipeline behaves exactly as before (no breaking change). - When
Namespaceis also set, both constraints are applied together: namespace setsVectorFilter.Namespace;StoreFiltercontributesMetadataMatchandScope. - If both an explicit
VectorFilterparameter andStoreFilterare present, theirMetadataMatchdictionaries are merged (StoreFilterwins on key conflicts).Scopeis taken fromStoreFilterwhen set. - Multiple metadata conditions are expressed via
VectorFilter.MetadataMatch(any number of key-value pairs, all combined with AND logic).
MergeStoreFilter(internal) โ merges explicitVectorFilterwith per-queryStoreFilter.
Usage
// Single metadata condition
var options = new RagQueryOptions();
options.FinalFilter.TopK = 5;
options.StoreFilter = VectorFilter.ByMetadata("storage_id", storageId);
var result = await ragStore.QueryAsync("์ง๋ฌธ", options, cancellationToken);
// Multiple conditions (AND) โ storage_id AND folder_path
options.StoreFilter = new VectorFilter
{
MetadataMatch = new Dictionary<string, string>
{
["storage_id"] = storageId,
["folder_path"] = "/docs/private"
}
};
// Namespace + metadata simultaneously
options.Namespace = "tenant-A";
options.StoreFilter = VectorFilter.ByMetadata("user_id", currentUserId);
Compatibility
- Requires
Mythosia.AI.Rag.Abstractionsv5.1.0. StoreFilter = null(default) preserves existing behavior.
v6.1.0
Added
onDocumentEmbeddedcallback parameter onBuildAsyncโ optionalFunc<IReadOnlyList<VectorRecord>, Task>?callback invoked after each document's embedding is complete.- When omitted (
null), the default behavior is unchanged โ records are saved to the configured store viaUpsertBatchAsyncas before. - When provided, the callback replaces the default
UpsertBatchAsynccall, giving full control over how records are persisted. - Enables atomic file replacement by combining with
IVectorStore.ReplaceByFilterAsync(Abstractions v2.3.0).
- When omitted (
Usage
// Default: works exactly as before (no callback, saves to store automatically)
var store = await RagStore.BuildAsync(builder =>
{
builder.AddDocuments("./docs/")
.UseOpenAIEmbedding(apiKey)
.UseStore(vectorStore);
}, ct);
// Atomic file replacement via callback
var store = await RagStore.BuildAsync(builder =>
{
builder.AddDocuments(loader, file.LocalPath)
.UseEmbedding(embeddingProvider)
.UseStore(vectorStore);
},
onDocumentEmbedded: records =>
vectorStore.ReplaceByFilterAsync(
VectorFilter.ByMetadata("full_path", file.FullPath), records, ct),
ct);
Compatibility
- Fully backward compatible with v6.0.1. No breaking changes โ omitting the callback preserves existing behavior.
v6.0.1
Mythosia.AI v5.0.1 Compatibility
- Compatible with
Mythosia.AIv5.0.1 โ inherits streaming Template Method refactor andStreamflag restoration fix during conversation summary. - No functional changes to RAG pipeline.
v6.0.0
Breaking Changes (requires Abstractions v5.0.0)
IReranker.RerankAsyncremovedtopKparameter โ all reranker implementations (CohereReranker,LlmReranker,VllmReranker) now return all results re-scored and reordered. TopK trimming is handled by the pipeline after final selection.IRetrievalStrategy.RetrieveAsyncqueryparameter now nullable โHybridRetrievalStrategyfalls back to dense-only search when the lexical query is null/empty.OllamaEmbeddingProvider/VllmEmbeddingProviderstrict dimension validation โdimensionsis nowreadonlywith constructor validation (> 0). Dimension mismatch with server response throwsInvalidOperationExceptioninstead of silently auto-correcting.
Added
- Weighted-blend final selection โ
RagBuilder.WithFinalSelectionPolicy(RagFinalSelectionMode.WeightedBlend, retrievalWeight)blends retrieval and reranker scores for final ranking instead of relying on reranker scores alone. - Retrieval keyword extraction in
LlmQueryRewriterโ whenextractKeywords: true(default), the rewriter outputs aKEYWORDS:line with shaped search terms for the text/keyword leg of hybrid search. Helps lexical retrieval handle language-particle and formatting mismatches. LlmQueryRewriterconfigurablemaxTokensโ control the LLM response token limit for query rewriting (default 250).RagBuilder.WithQueryRewriter(uint maxTokens)โ new overload to configure max tokens without providing a custom rewriter.RagPipelinereranked candidates tracking โRagProcessedQuery.RerankedCandidatesexposes all results after re-ranking but before final selection.RagStore/RagEnabledServicekeyword-derived text search โ when the rewriter produces keywords, they are joined and passed as the lexical query for hybrid search, separate from the semantic query used for embedding.VllmEmbeddingProvidersendsdimensionsparameter in the request body to the server.
Changed
LlmQueryRewriternow builds an inlineAIRequestProfilewith explicitTemperature,MaxTokens, andDisableReasoningsettings instead of usingRequestProfiles.QueryRewrite.CohereReranker/VllmRerankertop_nnow set toresults.Count(returns all results to the pipeline for final selection).LlmRerankerno longer applies.Take(topK)after scoring.HybridRetrievalStrategyskips BM25 entirely and falls back to dense vector search when lexical query is null or empty.
Migration Guide
// Before (v5.x) โ custom IReranker implementation
public Task<IReadOnlyList<VectorSearchResult>> RerankAsync(
string query, IReadOnlyList<VectorSearchResult> results,
int topK, CancellationToken ct = default)
// After (v6.0) โ remove topK parameter, return all results
public Task<IReadOnlyList<VectorSearchResult>> RerankAsync(
string query, IReadOnlyList<VectorSearchResult> results,
CancellationToken ct = default)
// Before (v5.x) โ custom IRetrievalStrategy implementation
public Task<IReadOnlyList<VectorSearchResult>> RetrieveAsync(
float[] denseVector, string query, int topK, ...)
// After (v6.0) โ query is now nullable
public Task<IReadOnlyList<VectorSearchResult>> RetrieveAsync(
float[] denseVector, string? query, int topK, ...)
// New: Weighted-blend final selection
.WithRag(rag => rag
.AddDocument("docs.txt")
.WithReranker(new CohereReranker(apiKey))
.WithFinalSelectionPolicy(RagFinalSelectionMode.WeightedBlend, retrievalWeight: 0.65)
)
v5.0.1
Breaking Changes (requires Abstractions v4.0.0)
RagPipelineOptions.TopK,MinScore,DefaultNamespace,RetrievalMultiplierremoved โ replaced byDefaultQueryproperty of typeRagQueryOptions, which containsFinalFilter,RetrievalDerivation, andNamespace.RagProcessedQuery.AugmentedPromptrenamed toRequestMessageContentโ clarifies the value is transient request-only content.RagProcessedQueryconstructor now requires an additionalIReadOnlyList<VectorSearchResult> retrievalCandidatesparameter.RagQueryDiagnosticsproperty renames โAppliedTopKโFinalTopK,RetrievalKโRetrievalTopK,AppliedMinScoreโAppliedFinalMinScore.LlmQueryRewriter.RewriteAsyncreturnsQueryRewriteResultinstead ofTask<string>โ includes search gate decision (NeedsSearch).RagQueryOptionsrestructured โint? TopK,double? MinScore,string? Namespacereplaced byRagFilter FinalFilter,RagRetrievalDerivation RetrievalDerivation,string Namespace.RagQueryResultconstructor now requiresretrievalCandidatesparameter (internal but affects custom pipeline implementations).
Added
VllmEmbeddingProviderโ vLLM-compatible OpenAI-style embedding provider (/v1/embeddings). Configurable model, dimensions, and base URL.VllmRerankerโ vLLM-compatible reranker (/v1/rerank). Supports Qwen3-Reranker and other vLLM-served models.RagStore.QueryAsyncwith conversation history โ new overloads acceptingIReadOnlyList<ConversationTurn>?for integrated query rewriting + search gate in a single call.RagStore.SetQueryRewriter(IQueryRewriter?)โ set or clear the query rewriter at runtime without rebuilding.- Search gate in
LlmQueryRewriterโ returns[PASS]for greetings/chitchat/non-search queries, skipping the RAG pipeline entirely (RagProcessedQuery.SearchSkipped = true). - Progress reporting โ
RagQueryOptions.ProgressAsynccallback invoked when the pipeline enters eachRagProgressStage(QueryRewrite,Embedding,Filtering,Retrieval,Reranking,ContextBuild). - Final MinScore filtering โ after re-ranking, results below
FinalFilter.MinScoreare discarded before context building. RagBuilder.WithRetrievalMultiplier(int)โ configure retrieval candidate multiplier at build time.RagBuilder.WithRetrievalMinScore(double)โ configure retrieval-stage score threshold at build time.RagProcessedQuery.RetrievalCandidatesโ raw retrieval candidates before re-ranking.RagProcessedQuery.SearchSkippedโ indicates the search gate bypassed the RAG pipeline.RagProcessedQuery.RewriteResultโ rawQueryRewriteResultfrom the query rewriter.RagQueryDiagnostics.AppliedRetrievalMinScoreโ retrieval-stage score threshold.RagQueryDiagnostics.RewriteElapsedMsโ time spent on query rewriting.
Changed
RagStoreconstructor simplified โqueryRewriterEnabledparameter removed; rewriter is now managed viaSetQueryRewriter().RagBuildernow buildsRagQueryOptionswithFinalFilter/RetrievalDerivationstructure instead of flat properties.MarkdownTextSplitterโ removed unusedIsAtomicBlockprivate method.
Migration Guide
// Before (v4.0)
store.UpdateOptions(opt =>
{
opt.TopK = 8;
opt.MinScore = 0.4;
opt.RetrievalMultiplier = 3;
opt.PromptTemplate = "...";
});
// After (v5.0)
store.UpdateOptions(opt =>
{
opt.DefaultQuery.FinalFilter.TopK = 8;
opt.DefaultQuery.FinalFilter.MinScore = 0.4;
opt.DefaultQuery.RetrievalDerivation.TopKMultiplier = 3;
opt.PromptTemplate = "...";
});
// Before (v4.0)
var result = await ragStore.QueryAsync("query", new RagQueryOptions { TopK = 15, MinScore = 0.2 });
Console.WriteLine(result.AugmentedPrompt);
Console.WriteLine(result.Diagnostics.AppliedTopK);
// After (v5.0)
var result = await ragStore.QueryAsync("query",
new RagQueryOptions { FinalFilter = new RagFilter { TopK = 15, MinScore = 0.2 } });
Console.WriteLine(result.RequestMessageContent);
Console.WriteLine(result.Diagnostics.FinalTopK);
v4.0.0
Breaking Changes
RagPipeline.SetContextBuilder()removed โ context builder is now resolved automatically fromRagPipelineOptions.PromptTemplateat query time with internal caching.RagStore.UpdateQuerySettings()removed โ replaced byRagStore.UpdateOptions(Action<RagPipelineOptions>).RagStore.UpdateRetrievalMultiplier()removed โ useUpdateOptionsinstead.
Migration Guide
// Before (v3.x)
store.UpdateQuerySettings(topK: 8, minScore: 0.4, promptTemplate: "...");
store.UpdateRetrievalMultiplier(3);
// After (v4.0)
store.UpdateOptions(opt =>
{
opt.TopK = 8;
opt.MinScore = 0.4;
opt.PromptTemplate = "...";
opt.RetrievalMultiplier = 3;
});
Added
- Auto-multiplier for re-ranking โ when a reranker is configured, the retrieval stage automatically fetches
TopK ร RetrievalMultipliercandidates, then the reranker selects the bestTopKfrom that wider pool. No API changes needed; singleTopKkeeps the API simple. RagStore.UpdateOptions(Action<RagPipelineOptions>)โ single method to update all pipeline options at runtime. New options added toRagPipelineOptionsare automatically available without modifyingRagStore.PromptTemplateinRagPipelineOptionsโRagPipelinelazily resolvesContextBuilderfromOptions.PromptTemplatewith caching, replacing the explicitSetContextBuilder()pattern.
Changed
RagBuilder.WithPromptTemplate()now setsRagPipelineOptions.PromptTemplateinstead of creating aTemplateContextBuilderat build time.
v3.2.0
Added
- Hybrid Search โ
UseHybridSearch()fluent API combines BM25 keyword search with vector similarity search via Reciprocal Rank Fusion (RRF).UseHybridSearch(float vectorWeight = 0.5f)โ adjustable balance between vector and keyword relevance.UseVectorSearch()โ explicit pure vector mode (same as default behavior).- Automatically selects the optimal strategy based on the store:
- Stores with native
IVectorStore.HybridSearchAsyncsupport (Postgres, Qdrant) โ native hybrid query delegation. - Non-hybrid stores (InMemory) โ application-level BM25 index + vector search + RRF merge.
- Stores with native
- Re-ranking โ
WithReranker(IReranker)fluent API re-orders search results after retrieval.CohereRerankerโ Cohere Rerank API v2 (rerank-v3.5default model).LlmRerankerโ uses anyAIServiceto score and reorder results via LLM.
- Retrieval Strategy abstraction โ
VectorRetrievalStrategyandHybridRetrievalStrategyimplementIRetrievalStrategyfor pluggable retrieval logic. RagPipelinenow accepts optionalIRetrievalStrategyandIRerankervia constructor injection.
Compatibility
- Fully backward compatible with v3.1.0. No breaking changes.
- Existing code without
UseHybridSearch()orWithReranker()behaves identically to v3.1.0 (pure vector search, no re-ranking).
v3.1.0
Added
WithQueryRewriter()fluent API for multi-turn RAG conversations.- Automatically rewrites follow-up queries (e.g., "Tell me more about that") into standalone queries using conversation history before vector search.
- Uses the inner
AIServiceas the LLM for rewriting by default. - Supports custom
IQueryRewriterimplementations viaWithQueryRewriter(IQueryRewriter).
LlmQueryRewriterโ defaultIQueryRewriterimplementation that uses anAIServiceinStatelessModefor rewriting without polluting conversation history.RagProcessedQuery.RewrittenQueryproperty for inspecting/debugging rewritten queries.
Compatibility
- Fully backward compatible with v3.0.0. No breaking changes.
v3.0.0
Breaking Changes
RagProcessedQueryconstruction is now diagnostics-first; call sites must provideRagQueryDiagnosticswhen creating instances directly.
Changed
Mythosia.AI.Ragdirectly referencesMythosia.VectorDb.InMemoryfor out-of-the-box defaults.- Default store resolution in
RagBuilder.BuildAsyncuses in-memory store creation when no custom store is configured. - RAG diagnostics now use
IRagDiagnosticsStore(fromMythosia.AI.Rag.Abstractions) for full chunk-level analysis capabilities. - Removed reflection-based in-memory diagnostics probing and switched to interface-based capability detection.
- Added per-request retrieval overrides via
RagQueryOptions(TopK,MinScore,Namespace) acrossIRagPipeline,RagStore, andRagEnabledService. RagProcessedQuerynow includesDiagnostics(RagQueryDiagnostics) with applied retrieval settings (AppliedNamespace,AppliedTopK,AppliedMinScore) andElapsedMsfor request-level observability.
v2.0.0
Breaking Changes
- Vector DB abstraction types (
IVectorStore,VectorRecord,VectorFilter,VectorSearchResult) moved toMythosia.VectorDbnamespace. InMemoryVectorStoremoved toMythosia.VectorDb.InMemorypackage (namespaceMythosia.VectorDb.InMemory).- Consumers must replace
using Mythosia.AI.VectorDB;withusing Mythosia.VectorDb.InMemory;. - Consumers must add
using Mythosia.VectorDb;for vector DB contract types.
Changed
- Improved
MarkdownTextSplitterbehavior for large markdown tables:- Large table blocks are now split by row within chunk budget.
- Table header/separator rows are preserved at the start of each split chunk.
- Code fence blocks remain unsplit.
ProcessAsyncnow returns the original query as-is when no references are found, instead of an empty context template that confuses the LLM.
v1.2.0
Changed
- Integrated
IDocumentParser-based loaders for Office and PDF sources. - Removed semantic splitter from
RagBuilder/RagPipeline.
Added
DocumentSourceBuilderfor per-extension routing with per-source loader/text splitter configuration.MarkdownTextSplitterโ splits on markdown headers.RecursiveTextSplitterโ recursive splitting with ordered separators.- Convenience document helpers:
AddWord,AddExcel,AddPowerPoint. - Per-source routing: single-file sources prioritized over directory sources; deduplicated by normalized full path.
Fixed
CharacterTextSplitteroverlap now aligns to separator boundaries.
v1.1.0
Added
- Convenience document helpers for Office files: AddWord, AddExcel, AddPowerPoint.
- DocumentSourceBuilder for per-extension routing with per-source loader/text splitter configuration.
- MarkdownTextSplitter (splits on markdown headers).
- RecursiveTextSplitter (recursive, ordered separators).
- Per-source routing updates: single-file sources take priority over directory sources and documents are deduplicated by normalized full path.
Fixed
- CharacterTextSplitter overlap now aligns to separator boundaries to avoid awkward mid-paragraph splits.
Compatibility
- Backward compatible with v1.0.0 (existing ITextSplitter usage unchanged).
Documentation
- RAG README expanded with per-extension routing examples.
v1.0.0
Initial Release
- RagPipeline + RagBuilder orchestration for indexing and querying.
- DefaultContextBuilder for query context construction.
- CharacterTextSplitter and TokenTextSplitter.
- OpenAIEmbeddingProvider and LocalEmbeddingProvider.
- PlainTextDocumentLoader integration for RAG sources.