MoonBit-native word embedding loader and lightweight semantic retrieval library
moon fmt --check
moon check --deny-warn
moon test --deny-warn
moon build
moon run cmd/main///|
test "README minimal search" {
let corpus = EmbeddingCorpus::from_glove_text(
"king 0.92 0.10 0.00\nqueen 0.90 0.14 0.00\n",
)
let index = MoonEmbedIndex::from_corpus(corpus, 3)
let report = index.search_token("king", 1)
inspect(report.hits[0].token, content="king")
}///|
test "README application workflow" {
let knowledge = support_knowledge_base()
let results = knowledge.ingest_many([
Document::new(
"faq-login",
"king queen",
metadata=Map([("category", "support")]),
),
])
inspect(results[0].accepted(), content="true")
let report = knowledge.search(ApplicationQuery::new("king", k=3))
inspect(report.is_empty(), content="false")
}pub(all) struct ApplicationAnswer {
found : Bool
query : String
document_id : String
text : String
category : String
score : Double
}pub(all) struct ApplicationDocumentSummary {
id : String
category : String
token_count : Int
known_token_count : Int
vector_ready : Bool
}pub(all) struct ApplicationKnowledgeBase {
corpus : EmbeddingCorpus
index : MoonEmbedIndex
store : DocumentStore
tokenizer : TextTokenizer
policy : IngestionPolicy
session : QuerySession
counters : UsageCounters
}fn ApplicationKnowledgeBase::admit_query(self : ApplicationKnowledgeBase, query : ApplicationQuery) -> QueryAdmissionfn ApplicationKnowledgeBase::answer(self : ApplicationKnowledgeBase, query : ApplicationQuery) -> ApplicationAnswerfn ApplicationKnowledgeBase::document_summaries(self : ApplicationKnowledgeBase) -> Array[ApplicationDocumentSummary]fn ApplicationKnowledgeBase::documents_for_category(self : ApplicationKnowledgeBase, category : String) -> Array[Document]fn ApplicationKnowledgeBase::export_category(self : ApplicationKnowledgeBase, category : String) -> Stringfn ApplicationKnowledgeBase::ingest(self : ApplicationKnowledgeBase, document : Document) -> IngestionResultfn ApplicationKnowledgeBase::ingest_many(self : ApplicationKnowledgeBase, documents : Array[Document]) -> Array[IngestionResult]fn ApplicationKnowledgeBase::ingest_with_report(self : ApplicationKnowledgeBase, documents : Array[Document]) -> IngestionBatchReportfn ApplicationKnowledgeBase::new(corpus : EmbeddingCorpus, signature_bits? : Int, tokenizer? : TextTokenizer, policy? : IngestionPolicy, session_name? : String) -> ApplicationKnowledgeBasefn ApplicationKnowledgeBase::search(self : ApplicationKnowledgeBase, query : ApplicationQuery) -> ApplicationSearchReportfn ApplicationKnowledgeBase::search_category(self : ApplicationKnowledgeBase, category : String, text : String, k? : Int) -> ApplicationSearchReportfn ApplicationKnowledgeBase::search_many(self : ApplicationKnowledgeBase, queries : Array[ApplicationQuery]) -> Array[ApplicationSearchReport]fn ApplicationKnowledgeBase::trace_query(self : ApplicationKnowledgeBase, query : ApplicationQuery) -> ApplicationQueryTracefn ApplicationKnowledgeBase::validate_document(self : ApplicationKnowledgeBase, document : Document) -> IngestionResultpub(all) struct ApplicationQuery {
text : String
k : Int
filter : DocumentFilter
threshold : Double?
}fn ApplicationQuery::new(text : String, k? : Int, filter? : DocumentFilter, threshold? : Double) -> ApplicationQuerypub(all) struct ApplicationQueryTrace {
admission : QueryAdmission
report : ApplicationSearchReport
}pub(all) struct ApplicationSearchReport {
query : ApplicationQuery
hits : Array[ApplicationHit]
candidates : Int
scanned : Int
unknown_terms : Int
filtered_documents : Int
}pub(all) struct BenchmarkDocument {
id : String
category : String
text : String
expected_tokens : Array[String]
}pub(all) struct BenchmarkReport {
suite : String
documents : Int
queries : Int
passed : Int
mean_recall : Double
mean_candidates : Double
filtered_documents : Int
}pub(all) struct BenchmarkSuite {
name : String
documents : Array[BenchmarkDocument]
queries : Array[RetrievalCase]
}fn BenchmarkSuite::documents_in_category(self : BenchmarkSuite, category : String) -> Array[BenchmarkDocument]fn BenchmarkSuite::sample_search(self : BenchmarkSuite, index : MoonEmbedIndex, repeats : Int, k : Int) -> SampleStatspub(all) struct CorpusCompatibility {
compatible : Bool
same_dimension : Bool
shared_tokens : Int
left_only : Int
right_only : Int
}pub(all) struct CorpusStats {
records : Int
dimension : Int
zero_vectors : Int
duplicate_tokens : Int
min_norm : Double
max_norm : Double
}fn DocumentFilter::matches(self : DocumentFilter, document : Document, tokenizer : TextTokenizer) -> Boolfn DocumentStore::add_document(self : DocumentStore, doc : Document, corpus : EmbeddingCorpus) -> Unitfn DocumentStore::add_documents(self : DocumentStore, documents : Array[Document], corpus : EmbeddingCorpus) -> Intfn DocumentStore::filter(self : DocumentStore, filter : DocumentFilter, tokenizer : TextTokenizer) -> Array[Document]fn DocumentStore::ranked_search(self : DocumentStore, query : Array[Double], filter_key : String?, filter_value : String?, k : Int) -> Array[RankedDocument]fn DocumentStore::search(self : DocumentStore, query_vector : Array[Double], filter_key : String?, filter_value : String?, k : Int) -> Array[Document]fn DocumentStore::search_scored(self : DocumentStore, query_vector : Array[Double], filter_key : String?, filter_value : String?, k : Int, threshold : Double) -> Array[DocumentHit]fn DocumentStore::search_text(self : DocumentStore, corpus : EmbeddingCorpus, text : String, filter_key : String?, filter_value : String?, k : Int) -> Array[Document]fn DocumentStore::upsert(self : DocumentStore, document : Document, corpus : EmbeddingCorpus) -> Boolpub(all) struct EmbeddingCorpus {
records : Array[EmbeddingRecord]
token_index : Map[String, Int]
dim : Int
source : SourceFormat
}fn EmbeddingCorpus::from_records(records : Array[EmbeddingRecord], source : SourceFormat) -> EmbeddingCorpusfn EmbeddingCorpus::phrase_embedding(self : EmbeddingCorpus, phrase : PhraseQuery) -> Array[Double]?fn EmbeddingCorpus::prefix(self : EmbeddingCorpus, prefix : String, limit : Int) -> Array[EmbeddingRecord]fn EmbeddingCorpus::sentence_embedding_with_tokenizer(self : EmbeddingCorpus, text : String, tokenizer : TextTokenizer) -> Array[Double]?pub(all) struct IndexDiagnostics {
records : Int
dimension : Int
signature_bits : Int
nonempty_buckets : Int
largest_bucket : Int
}pub(all) struct IngestionBatchReport {
attempted : Int
accepted : Int
rejected : Int
skipped : Int
diagnostics : Array[IngestionIssue]
}pub(all) struct IngestionIssue {
code : String
message : String
document_id : String
}pub(all) struct IngestionPolicy {
max_documents : Int
min_tokens : Int
require_category : Bool
reject_unknown_only : Bool
replace_existing : Bool
}pub(all) struct IngestionResult {
document_id : String
status : IngestionStatus
token_count : Int
known_token_count : Int
issues : Array[IngestionIssue]
}pub(all) enum IngestionStatus {
Accepted
Rejected
Skipped
}pub(all) struct MoonEmbedIndex {
corpus : EmbeddingCorpus
buckets : Array[Array[Int]]
signature_bits : Int
}fn MoonEmbedIndex::evaluate(self : MoonEmbedIndex, cases : Array[RetrievalCase], k : Int) -> RetrievalMetricsfn MoonEmbedIndex::execute_plan(self : MoonEmbedIndex, query : Array[Double], plan : QueryPlan) -> SearchReportfn MoonEmbedIndex::safe_search(self : MoonEmbedIndex, query : Array[Double], plan : QueryPlan) -> (ValidationReport, SearchReport)fn MoonEmbedIndex::search_exact(self : MoonEmbedIndex, query : Array[Double], k : Int) -> SearchReportfn MoonEmbedIndex::search_explained(self : MoonEmbedIndex, query : Array[Double], k : Int, profile : ScoreProfile) -> Array[ExplainedHit]fn MoonEmbedIndex::search_many(self : MoonEmbedIndex, queries : Array[Array[Double]], k : Int) -> Array[SearchReport]fn MoonEmbedIndex::search_phrase(self : MoonEmbedIndex, phrase : PhraseQuery, k : Int) -> SearchReportfn MoonEmbedIndex::search_threshold(self : MoonEmbedIndex, query : Array[Double], k : Int, threshold : Double) -> SearchReportfn MoonEmbedIndex::search_tokenized(self : MoonEmbedIndex, text : String, tokenizer : TextTokenizer, k : Int) -> SearchReportpub(all) struct QueryAdmission {
accepted : Bool
normalized : String
token_count : Int
known_token_count : Int
reason : String
}pub(all) struct QueryEvent {
sequence : Int
query : ApplicationQuery
result_count : Int
top_score : Double
candidates : Int
}pub(all) struct QuerySession {
name : String
max_events : Int
events : Array[QueryEvent]
next_sequence : Int
}fn QuerySession::record(self : QuerySession, query : ApplicationQuery, report : ApplicationSearchReport) -> Unitpub(all) struct RankedDocument {
id : String
score : Double
category : String
}pub(all) struct RankingSummary {
total : Int
nonempty : Int
top_score : Double
average_score : Double
}pub(all) struct RetrievalMetrics {
cases : Int
passed : Int
mean_recall : Double
mean_candidates : Double
}pub(all) enum RetrievalMode {
Exact
Approximate
Auto
}pub(all) struct SampleStats {
count : Int
total : Double
minimum : Double
maximum : Double
}pub(all) struct ScenarioMatrixReport {
scenarios : Int
passed : Int
total_documents : Int
total_queries : Int
total_rejected : Int
total_skipped : Int
}pub(all) struct ScenarioReport {
name : String
ingested : Int
rejected : Int
skipped : Int
queries : Int
nonempty_queries : Int
expected_matches : Int
observed_matches : Int
expected_rejected : Int
expected_skipped : Int
}pub(all) struct ScoreComponents {
lexical : Double
semantic : Double
freshness : Double
popularity : Double
}pub(all) struct ScoreProfile {
lexical_weight : Double
semantic_weight : Double
freshness_weight : Double
popularity_weight : Double
}pub(all) struct SearchHit {
token : String
score : Double
}pub(all) enum SourceFormat {
Word2VecText
Word2VecBinary
GloVeText
}pub(all) struct TextReport {
characters : Int
raw_terms : Int
retained_terms : Int
unique_terms : Int
stop_words : Int
}pub(all) struct TextToken {
text : String
position : Int
original_length : Int
}pub(all) struct TextTokenizer {
lowercase : Bool
keep_numbers : Bool
min_length : Int
stop_words : Map[String, Bool]
}fn TextTokenizer::new(lowercase? : Bool, keep_numbers? : Bool, min_length? : Int, stop_words? : Map[String, Bool]) -> TextTokenizerpub(all) struct ThresholdPolicy {
minimum_score : Double
maximum_results : Int
require_nonempty : Bool
}fn ThresholdPolicy::new(minimum_score? : Double, maximum_results? : Int, require_nonempty? : Bool) -> ThresholdPolicypub(all) struct UsageCounters {
ingestion_attempts : Int
accepted_documents : Int
rejected_documents : Int
skipped_documents : Int
query_attempts : Int
empty_queries : Int
returned_hits : Int
scanned_candidates : Int
}pub(all) struct ValidationFinding {
severity : ValidationSeverity
code : String
message : String
token : String?
}pub(all) struct ValidationReport {
findings : Array[ValidationFinding]
checked_records : Int
checked_dimensions : Int
}pub(all) enum ValidationSeverity {
Info
Warning
Error
}fn application_operations_smoke() -> Boolfn quantize_coordinate(value : Double, levels : Int) -> IntMoonBit-native word embedding loader and lightweight semantic retrieval library