SDK audit fixes: restore MetalRT enum, trim Android backend labels, sync web yarn.lock#531
SDK audit fixes: restore MetalRT enum, trim Android backend labels, sync web yarn.lock#531Siddhesh2377 wants to merge 46 commits into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR updates RAG query contracts, backend snapshot/dedup behavior, retrieval fusion and reranking, client toggles, validation tests, and Android model display mappings. It also adds a React Native package build script. ChangesInference Framework UI Mapping and Enum Documentation
RAG Retrieval Controls, Persistence, and Hashing
React Native Package Build Script
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… scoped retrieval + example app toggles
There was a problem hiding this comment.
Actionable comments posted: 10
🧹 Nitpick comments (2)
sdk/runanywhere-commons/src/features/rag/rag_backend.cpp (1)
670-691: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winRedundant
all_chunk_texts()enumeration.
vector_store_->all_chunk_texts()is called at Line 673 (BM25 rebuild) and again at Line 683 (dedup rebuild), re-materializing every chunk id/text twice on load. Enumerate once and reuse.♻️ Reuse a single enumeration
- if (bm25_index_) { - bm25_index_->clear(); - const auto texts = vector_store_->all_chunk_texts(); - if (!texts.empty()) - bm25_index_->add_chunks_batch(texts); - } + const auto texts = vector_store_->all_chunk_texts(); + if (bm25_index_) { + bm25_index_->clear(); + if (!texts.empty()) + bm25_index_->add_chunks_batch(texts); + } { std::lock_guard<std::mutex> lock(mutex_); next_chunk_id_ = static_cast<size_t>(nid); // Rebuild the content-addressed dedup set from restored chunk metadata // so a re-ingest after restart is still skipped. ingested_content_hashes_.clear(); - for (const auto& [id, text] : vector_store_->all_chunk_texts()) { + for (const auto& [id, text] : texts) { (void)text;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sdk/runanywhere-commons/src/features/rag/rag_backend.cpp` around lines 670 - 691, The restore path in rag_backend.cpp is enumerating vector_store_->all_chunk_texts() twice: once for rebuilding bm25_index_ and again for rebuilding ingested_content_hashes_. Change the rebuild logic in the same restore block to materialize the chunk id/text list once and reuse that cached collection for both BM25 rebuild and dedup metadata restoration, keeping the existing behavior in bm25_index_->add_chunks_batch and the ingested_content_hashes_ loop.idl/rag.proto (1)
216-224: 🚀 Performance & Scalability | 🔵 TrivialMissing upper bound on
multi_query_count.
rac_min = 1is declared but there's norac_max. Combined withrac_rag_proto_abi.cpppassing this value through unclamped (see comment there), a caller can request an arbitrarily large fan-out of query rewrites/retrievals. Consider adding arac_maxannotation here for documentation/codegen parity withRAGConfiguration.top_k-style bounded fields.
[recommended_refactor_low_effort_high_reward]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@idl/rag.proto` around lines 216 - 224, The multi-query count field is only bounded on the minimum side, so add an upper-limit annotation to the multi_query_count definition to match other bounded configuration fields. Update the rag.proto declaration for multi_query_count to include a rac_max value alongside rac_default and rac_min, keeping the limit consistent with the rest of the RAG config and allowing codegen to enforce the cap.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/ui/screens/rag/RagViewModel.kt`:
- Around line 93-112: The rerank toggle rebuild in updateRerank only logs
failures, so a failed ragCreatePipeline can leave the pipeline torn down while
rerankEnabled remains changed. Update updateRerank to treat the rebuild as
transactional: capture the previous rerank state, guard against overlapping
rebuilds, and if ragDestroyPipeline()/ragCreatePipeline() fails, restore the old
toggle state and surface an error the UI can react to. Keep the successful path
that refreshes chunkCount from ragGetStatistics(), and use the existing
RACLog/error handling around the rebuild flow.
In `@examples/flutter/RunAnywhereAI/lib/features/rag/rag_view_model.dart`:
- Around line 82-94: The rerank toggle path in setRerankEnabled mutates
_rerankEnabled before awaiting RunAnywhere.rag.destroyPipeline(), so add the
same try/catch and _error handling pattern used in loadDocument to keep state
consistent if pipeline teardown fails. Make sure setRerankEnabled either rolls
back the flag or leaves the model in a coherent error state, sets _error, and
still calls notifyListeners so the UI can react when destroyPipeline throws.
In `@examples/react-native/RunAnywhereAI/src/screens/RAGScreen.tsx`:
- Around line 221-229: `handleRerankChange` currently awaits `handleClearAll()`
without guarding failures, so a rejected pipeline teardown can leave
`rerankEnabled` updated while the UI state is stale. Update the
`handleRerankChange` callback in `RAGScreen` to wrap the `handleClearAll()` call
in try/catch, and on failure surface the error with `setError` the same way
`handleSelectDocument` and `handleAskQuestion` do. Keep the optimistic
`setRerankEnabled` behavior only if you can recover cleanly, and ensure any
teardown error is handled so `RunAnywhere.ragDestroyPipeline()` rejection does
not become unhandled.
In `@sdk/runanywhere-commons/src/features/rag/rac_rag_proto_abi.cpp`:
- Around line 617-625: Clamp or validate the value assigned to
RAGBackend::QueryOverrides::multi_query_count before it is copied from
query_proto in rac_rag_proto_abi.cpp. The current parsing path in the query
override setup accepts any large caller-provided value when enable_multi_query
is enabled, so add an upper bound check or reject out-of-range inputs before
forwarding the value to the graph. Keep the fix localized to the overrides
construction around query_proto.multi_query_count() so the downstream
RAGGraphInputs::multi_query_count never receives an unbounded count.
In `@sdk/runanywhere-commons/src/features/rag/rag_backend.cpp`:
- Around line 281-287: The add_document() path in rag_backend.cpp is rewriting
the full RAG snapshot on every ingest by calling save_index() after each
document, which makes bulk ingestion quadratic. Change the persistence flow
around add_document() and save_index() so writes are coalesced per batch or
exposed through an explicit flush/save step, and only serialize the vector store
once after a batch of documents has been ingested when config_.persist_index and
config_.index_path are enabled.
- Around line 180-193: `rag_backend::add_document` currently checks
`ingested_content_hashes_` under `mutex_` but reserves the hash only later,
allowing concurrent same-content ingests to both proceed. Move the content-hash
reservation into the same locked section as the `count()` check, or keep the
lock held through the ingest path, so a second call sees the hash as already
claimed before any re-chunking or embedding starts.
In `@sdk/runanywhere-commons/src/features/rag/rag_fusion.cpp`:
- Around line 74-84: The prefix-trimming logic in rag_fusion.cpp is too
aggressive because it strips any leading digit from query variants, which
removes valid content like numbered terms and acronyms. Update the trimming in
the variant parsing block that builds v so it only removes explicit list markers
such as N. or N) (and the existing whitespace/punctuation), and do not treat
bare leading digits as removable numbering.
In `@sdk/runanywhere-commons/src/features/rag/vector_store_usearch.cpp`:
- Around line 332-345: In load_from_bytes, replace the truncation checks around
idx_len and js_len with overflow-safe bounds validation that compares each
decoded length against the remaining buffer space instead of using pos + length,
and make sure every failure path clears the current store state. On both the
truncated-section returns and the USearch load error path, reset the existing
index/chunks before returning false so the function’s failure behavior matches
its contract.
In `@sdk/runanywhere-commons/tests/test_rag_e2e.cpp`:
- Around line 78-92: `adapter_file_read` does not handle a failed
`std::ifstream::tellg()` result, so a `-1` length can be converted into a huge
`size_t` while still allocating only a 1-byte buffer. Update the logic in
`adapter_file_read` to detect `tellg()` failure before allocating, return an
error when the stream position is invalid, and only assign `out_data`/`out_size`
after confirming a non-negative size so the reported size always matches the
allocated buffer.
In `@sdk/shared/proto-ts/src/convenience/rag_convenience.ts`:
- Line 75: The validation message in the `rag_convenience.ts` logic is awkward
because it says “must be in >= 1”; update the error text used for
`multi_query_count` to remove the stray “in” and keep the wording grammatically
correct. Locate the message in the `m.multiQueryCount` check and adjust only the
string while preserving the same validation behavior.
---
Nitpick comments:
In `@idl/rag.proto`:
- Around line 216-224: The multi-query count field is only bounded on the
minimum side, so add an upper-limit annotation to the multi_query_count
definition to match other bounded configuration fields. Update the rag.proto
declaration for multi_query_count to include a rac_max value alongside
rac_default and rac_min, keeping the limit consistent with the rest of the RAG
config and allowing codegen to enforce the cap.
In `@sdk/runanywhere-commons/src/features/rag/rag_backend.cpp`:
- Around line 670-691: The restore path in rag_backend.cpp is enumerating
vector_store_->all_chunk_texts() twice: once for rebuilding bm25_index_ and
again for rebuilding ingested_content_hashes_. Change the rebuild logic in the
same restore block to materialize the chunk id/text list once and reuse that
cached collection for both BM25 rebuild and dedup metadata restoration, keeping
the existing behavior in bm25_index_->add_chunks_batch and the
ingested_content_hashes_ loop.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0cb843d0-3226-47a2-86d8-2807e6305baa
⛔ Files ignored due to path filters (11)
sdk/runanywhere-commons/src/generated/proto/rag.pb.ccis excluded by!**/generated/**sdk/runanywhere-commons/src/generated/proto/rag.pb.his excluded by!**/generated/**sdk/runanywhere-flutter/packages/runanywhere/lib/generated/convenience/ra_convenience.dartis excluded by!**/generated/**sdk/runanywhere-flutter/packages/runanywhere/lib/generated/rag.pb.dartis excluded by!**/generated/**sdk/runanywhere-kotlin/src/main/kotlin/com/runanywhere/sdk/generated/ai/runanywhere/proto/v1/RAGConfiguration.ktis excluded by!**/generated/**sdk/runanywhere-kotlin/src/main/kotlin/com/runanywhere/sdk/generated/ai/runanywhere/proto/v1/RAGQueryOptions.ktis excluded by!**/generated/**sdk/runanywhere-kotlin/src/main/kotlin/com/runanywhere/sdk/generated/convenience/RAConvenience.ktis excluded by!**/generated/**sdk/shared/proto-ts/dist/convenience/rag_convenience.d.tsis excluded by!**/dist/**sdk/shared/proto-ts/dist/convenience/rag_convenience.jsis excluded by!**/dist/**sdk/shared/proto-ts/dist/rag.d.tsis excluded by!**/dist/**sdk/shared/proto-ts/dist/rag.jsis excluded by!**/dist/**
📒 Files selected for processing (31)
examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/ui/screens/rag/RagScreen.ktexamples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/ui/screens/rag/RagViewModel.ktexamples/flutter/RunAnywhereAI/lib/features/rag/rag_demo_view.dartexamples/flutter/RunAnywhereAI/lib/features/rag/rag_view_model.dartexamples/react-native/RunAnywhereAI/src/screens/RAGScreen.tsxidl/rag.protosdk/runanywhere-commons/AGENTS.mdsdk/runanywhere-commons/CMakeLists.txtsdk/runanywhere-commons/include/rac/foundation/rac_sha256.hsdk/runanywhere-commons/src/features/rag/CMakeLists.txtsdk/runanywhere-commons/src/features/rag/rac_rag_proto_abi.cppsdk/runanywhere-commons/src/features/rag/rag_backend.cppsdk/runanywhere-commons/src/features/rag/rag_backend.hsdk/runanywhere-commons/src/features/rag/rag_fusion.cppsdk/runanywhere-commons/src/features/rag/rag_fusion.hsdk/runanywhere-commons/src/features/rag/rag_pipeline_graph.cppsdk/runanywhere-commons/src/features/rag/rag_pipeline_graph.hsdk/runanywhere-commons/src/features/rag/rag_rerank.cppsdk/runanywhere-commons/src/features/rag/rag_rerank.hsdk/runanywhere-commons/src/features/rag/vector_store_usearch.cppsdk/runanywhere-commons/src/features/rag/vector_store_usearch.hsdk/runanywhere-commons/src/foundation/rac_sha256.cppsdk/runanywhere-commons/src/infrastructure/http/rac_http_download.cppsdk/runanywhere-commons/tests/CMakeLists.txtsdk/runanywhere-commons/tests/data/rag_sample.mdsdk/runanywhere-commons/tests/test_rag_e2e.cppsdk/runanywhere-commons/tests/test_rag_fusion.cppsdk/runanywhere-commons/tests/test_rag_rerank.cppsdk/runanywhere-commons/tests/test_sha256.cppsdk/shared/proto-ts/src/convenience/rag_convenience.tssdk/shared/proto-ts/src/rag.ts
✅ Files skipped from review due to trivial changes (3)
- sdk/runanywhere-commons/tests/data/rag_sample.md
- sdk/runanywhere-commons/AGENTS.md
- sdk/runanywhere-commons/src/features/rag/rag_rerank.cpp
| uint64_t idx_len = 0; | ||
| if (!get_u64(idx_len) || pos + idx_len > size) { | ||
| LOGE("load: truncated index section"); | ||
| return false; | ||
| } | ||
| const uint8_t* idx_ptr = data + pos; | ||
| pos += idx_len; | ||
|
|
||
| // Load metadata from JSON file | ||
| std::string metadata_path = path + ".metadata.json"; | ||
| std::ifstream metadata_file(metadata_path); | ||
| if (!metadata_file) { | ||
| RAC_LOG_ERROR(LOG_TAG, "Failed to open metadata file: %s", metadata_path.c_str()); | ||
| uint64_t js_len = 0; | ||
| if (!get_u64(js_len) || pos + js_len > size) { | ||
| LOGE("load: truncated metadata section"); | ||
| return false; | ||
| } | ||
| const std::string js(reinterpret_cast<const char*>(data + pos), js_len); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
sed -n '280,390p' sdk/runanywhere-commons/src/features/rag/vector_store_usearch.cppRepository: RunanywhereAI/runanywhere-sdks
Length of output: 4451
🏁 Script executed:
rg -n "reset-to-empty|load:|clear\(\)|load_from_bytes|load\(" sdk/runanywhere-commons/src/features/rag/vector_store_usearch.cpp sdk/runanywhere-commons/src/features/rag -g '!**/build/**'Repository: RunanywhereAI/runanywhere-sdks
Length of output: 7041
🏁 Script executed:
sed -n '1,220p' sdk/runanywhere-commons/src/features/rag/vector_store_usearch.h && printf '\n---\n' && sed -n '620,710p' sdk/runanywhere-commons/src/features/rag/rag_backend.cppRepository: RunanywhereAI/runanywhere-sdks
Length of output: 7944
🏁 Script executed:
rg -n "load_index\(" sdk/runanywhere-commons/src/features/rag -g '!**/build/**' && printf '\n---\n' && sed -n '1,180p' sdk/runanywhere-commons/src/features/rag/rag_backend.cppRepository: RunanywhereAI/runanywhere-sdks
Length of output: 6662
Use overflow-safe length checks and clear state on all load failures. sdk/runanywhere-commons/src/features/rag/vector_store_usearch.cpp:332-345
pos + idx_len / pos + js_len can wrap on crafted lengths, so compare against the remaining space instead. Also, load_from_bytes() promises to reset the store on any failure, but the truncation and USearch-load error paths return without clearing the existing index/chunks.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@sdk/runanywhere-commons/src/features/rag/vector_store_usearch.cpp` around
lines 332 - 345, In load_from_bytes, replace the truncation checks around
idx_len and js_len with overflow-safe bounds validation that compares each
decoded length against the remaining buffer space instead of using pos + length,
and make sure every failure path clears the current store state. On both the
truncated-section returns and the USearch load error path, reset the existing
index/chunks before returning false so the function’s failure behavior matches
its contract.
…ed for dependent packages
…larity floor, fix clear() crash, single-document demos
…d]] build under -Werror
…); drop removed GENIE/METALRT enum cases (flutter)
…i-turn memory (llamacpp history)
- Introduced secure storage for Hugging Face tokens in SettingsRepository. - Updated SingleFileModel to include metadata for models requiring Hugging Face authentication. - Added new model entries in ModelCatalog, including various embedding models. - Improved UI components in SettingsScreen and ModelRow to reflect new functionalities. - Removed HexagonNpuCard and related references from the MoreScreen and AppNavigationDrawer. - Refactored model filtering logic in ModelSelectionSheet to streamline user experience.
…toggle, chat/composer/picker redesign - design-system.css: warm-neutral dark+light palettes replacing slate, brandStrong #E65500, elevation/motion/focus tokens, [data-theme] attribute theming, reduced-motion support - app.ts: topbar theme toggle (sun/moon, localStorage persistence, meta theme-color sync) - chat: hero empty state with time-based greeting and icon starter cards, user brand bubble + full-width assistant replies, streaming cursor, copy hover action, styled thinking disclosure and code blocks, auto-growing pill composer with focus ring - model picker: sectioned catalog (Active / On this device / Available), descriptions, Thinking badge, consumer verbs (Use / Active), progress pill, desktop centered dialog - shell: drawer accent bar + eased mobile drawer/scrim, designed feature-unavailable states, accel badge moved out of toolbar collision, storage view slate hardcodes replaced with tokens Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVaAg47Fr9BvxMwAVv4hBB
…title to RunAnywhere Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVaAg47Fr9BvxMwAVv4hBB
…mbient hero glow Drawer loses duplicate Documents/Images/Talk entries (the composer attach menu owns those flows) and nav descriptions; ghost icon buttons, borderless recents, brand New chat pill, hidden duplicate brand header on desktop; attach menu drops Advanced tools; composer radius 28. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVaAg47Fr9BvxMwAVv4hBB
- Empty state hero: brand glyph in tinted circle, time-based greeting, privacy subtitle (matches iOS/web) - Assistant replies read as full-width documents (no bubble) with bodyLarge type; pulsing brand streaming cursor on the generating tail - User bubble: brand asymmetric shape, comfier padding, width via new Dimens.bubbleMaxWidth - Dark scheme primary = BrandOrange #FF5500 (onPrimary white) aligning brand moments with iOS/web - TypingDots tinted primary; VisionLiveMode LIVE dot uses primaryGreen token instead of iOS system green - Send/stop haptic feedback Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVaAg47Fr9BvxMwAVv4hBB
…replies, pill composer, drawer, haptics, token sweep - Empty state hero: brand glyph, time-based greeting, 2x2 icon starter chips (adaptive grid replaces fixed 160pt scroll) - Assistant replies read as full-width documents (no bubble); user keeps brand gradient bubble; pulsing streaming cursor on the generating tail; copy via context menu - Floating pill composer with focus ring, send morphs to stop while generating - TypingIndicator simplified to leading brand dots - Drawer: brand New chat pill, persistent search, always-visible Recents, Settings pinned bottom, selection haptics - Haptics helper (UIKit + NSHapticFeedbackManager for macOS trackpads); wired to send/stop/talk/chips/toast - Settings regrouped consumer-first (Personalization, Tool Calling, Models, Privacy, Advanced disclosure incl. private downloads, About) - Mechanical token sweep across 16 files: ~71 raw colors -> AppColors, 14 fonts -> AppTypography, 22 radii -> AppSpacing Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVaAg47Fr9BvxMwAVv4hBB
dist/convenience/{embeddings_options,rag}_convenience.js were stale relative
to a tsc rebuild; regenerated per idl-drift-check.yml instructions.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HVaAg47Fr9BvxMwAVv4hBB
QHexRT bundles only run on Qualcomm Hexagon silicon; registering them on iOS/macOS just filled every picker with 40+ permanently-unavailable rows. Drop the private HNPU catalog specs, registration, and fallback merge; filter any stale qhexrt registry entries out of the model list; remove the QHexRT backend filter chip and 'requires Android device' messaging; HF token settings copy now speaks generically about private repos. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVaAg47Fr9BvxMwAVv4hBB
Define the canonical cross-platform rule in C++ so every SDK inherits it: - Apple-only frameworks (MLX, Foundation Models, CoreML, Swift Transformers, FluidAudio) are hidden from model list/query results on Android, WASM, Linux, and Windows. - Qualcomm QHexRT is hidden everywhere except Android. - All other frameworks (llama.cpp, ONNX, Sherpa, system TTS, cloud, ...) remain visible on every platform. New public C API rac_framework_supported_on_platform() (proto wire value, compile-time matrix, static_asserts pin the enum values). The filter funnels through the registry list/query paths only — registration, get-by-id, and download paths are untouched; registering an unsupported model logs a debug note and stays merge-compatible with catalog re-seeds. Exported for WASM. android example: drop the dead MLX/Apple backend filter chips (those frameworks never surface on Android now). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVaAg47Fr9BvxMwAVv4hBB
…ath configuration for Android. Introduce functions to check for required skel files and append paths accordingly. Update JNI interface to allow setting the skel directory from Kotlin. Adjust build scripts to include skel assets in the appropriate directories.
…PU detection. Introduce a new `HardwareTier` enum to categorize devices and update `DeviceInfo` to include NPU presence. Implement model family grouping and recommendations based on device capabilities, improving the user experience in model selection. Add UI components to display device tier and NPU status in the `DeviceStatusCard`. Refactor model selection logic to prioritize device-appropriate models, ensuring a tailored experience for users.
…`BackendBadge` to use a neutral color scheme and adjust icon sizes. Implement cleaner display titles for models by stripping unnecessary tokens and noise. Revise model selection UI to consistently show size labels and backend information. Remove deprecated advanced disclosure functionality for a more streamlined interface. Improve overall layout and readability in model rows and selection sheets.
| return name | ||
| // Quant tokens: Q8_0, Q4_K_M, Q6_K, F16, BF16, DWQ, 4bit/8-bit, int8… | ||
| .replace(/\b(?:Q\d+(?:_[A-Z0-9]+)*|BF16|F16|F32|DWQ|INT[48]|\d+\s?-?bits?)\b/gi, '') | ||
| // Parenthesized backend/format tokens — the backend shows as its own pill. | ||
| .replace(/\((?:ONNX|GGUF|MLX)\)/gi, '') |
Populates the previously-NULL embedding_ops slot with g_qhexrt_embeddings_ops, a vtable over the QHexRT C ABI: session_open -> qhx_generate(text) -> read qhx_output.embedding (L2-normalized sentence vector) into rac_embeddings_result_t. Mirrors the STT/LLM adapters; embed_batch loops embed. Registers RAC_PRIMITIVE_EMBED so commons routes embedding models with framework=QHEXRT to QHexRT (previously rejected with 'Backend not ready'). Validated on v75: embeddinggemma_300m (768-d) + nv_embedqa_1b (2048-d) produce semantically-separated vectors; nv_rerankqa_1b runs (scalar rerank score).
NpuModelE2ETest now dispatches MODEL_CATEGORY_EMBEDDING -> runEmbedding via RunAnywhere.embeddings.embed. Self-consistent gate (no external gold vector): a paraphrase pair must be more cosine-similar to the anchor than an unrelated sentence by >= EMBED_MARGIN (0.05). Rerankers (dim<=1 scalar score) are reported as reranker_ran, not a misleading semantic FAIL. v75 results: embeddinggemma_300m margin 0.68, nv_embedqa_1b margin 0.83, nv_rerankqa_1b runs.
…p2 zero-shot classify)
… (image vs label vs distractor)
…cancellation/auth events
…canary-qwen-2.5b-llm.json; register -423 not-found on v75)
…ry-fixes telemetry: stop double counting, fake metrics, and dropped events
qhexrt: embedding modality (RAC_PRIMITIVE_EMBED) + siglip2 zero-shot via embed API + NPU E2E gate
Summary
RAC_FRAMEWORK_METALRT, Android backend label cleanup, and web lockfile sync.Type of Change
Labels
Suggested labels:
bug,enhancement,android-sample,flutter-sample,react-native-sample,web-sdk,kotlin-sdk.Testing
SDKs
ctest -R rag)Example apps
Focused review-comment checks run on this branch:
gh api --paginateand verified counts.git diff --check.python3 -m py_compile idl/codegen/generate_ts_convenience.py.dart format --set-exit-if-changedon touched Dart files.python3 idl/codegen/generate_ts_convenience.py.Checklist
Screenshots / Recordings
N/A. The changes are SDK, native core, generated bindings, and example-app state handling; no visual UI layout change requires screenshots.