Skip to content

SDK audit fixes: restore MetalRT enum, trim Android backend labels, sync web yarn.lock#531

Open
Siddhesh2377 wants to merge 46 commits into
mainfrom
siddhesh/sdk-audit-fixes-v2
Open

SDK audit fixes: restore MetalRT enum, trim Android backend labels, sync web yarn.lock#531
Siddhesh2377 wants to merge 46 commits into
mainfrom
siddhesh/sdk-audit-fixes-v2

Conversation

@Siddhesh2377

@Siddhesh2377 Siddhesh2377 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Type of Change

  • Bug fix
  • Feature / behavior improvement
  • Generated code update
  • Example app update
  • Test coverage / test utility update
  • Documentation-only change

Labels

Suggested labels: bug, enhancement, android-sample, flutter-sample, react-native-sample, web-sdk, kotlin-sdk.

Testing

SDKs

  • commons — builds and RAG ctests pass (ctest -R rag)
  • Kotlin
  • Swift after proto regeneration, if needed
  • Flutter
  • React Native
  • Web

Example apps

  • Android
  • iOS
  • Flutter
  • React Native
  • Web

Focused review-comment checks run on this branch:

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.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The 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.

Changes

Inference Framework UI Mapping and Enum Documentation

Layer / File(s) Summary
Update backend badge and label/icon mappings
examples/android/.../BackendBadge.kt, examples/android/.../ModelDisplay.kt
backendBadgeColor() maps INFERENCE_FRAMEWORK_BUILT_IN to primaryGreen, and shortLabel(), consumerBackendLabel(), and backendIcon() remove explicit GENIE and METALRT cases so those frameworks use fallback mappings.
Clarify retired enum values in native header
sdk/runanywhere-commons/include/rac/infrastructure/model_management/rac_model_types.h
Comment above RAC_FRAMEWORK_METALRT is updated to explicitly name retired values 9 and 11 while preserving the numeric gap.

RAG Retrieval Controls, Persistence, and Hashing

Layer / File(s) Summary
Extend RAG query contracts
idl/rag.proto, sdk/shared/proto-ts/src/rag.ts, sdk/shared/proto-ts/src/convenience/rag_convenience.ts
RAGQueryOptions makes similarity_threshold optional and adds enable_multi_query, multi_query_count, and scope_prefix; generated bindings, defaults, and validation are updated to match.
Add snapshot, dedup, and hashing support
sdk/runanywhere-commons/.../rag_backend.*, vector_store_usearch.*, rac_sha256.*, rac_http_download.cpp, CMakeLists.txt, AGENTS.md
The backend tracks content hashes, persists and restores index snapshots, fingerprints snapshot validity, forwards rerank and query overrides, and switches to shared SHA-256 plus byte-based vector-store serialization.
Add fusion, rerank, and multi-query graph flow
sdk/runanywhere-commons/src/features/rag/rag_fusion.*, rag_rerank.*, rag_pipeline_graph.*, sdk/runanywhere-commons/src/features/rag/CMakeLists.txt
Reciprocal Rank Fusion, LLM pointwise reranking, and multi-query expansion are added to the retrieval graph and wired into the build.
Expose retrieval toggles in client UIs
examples/android/.../RagScreen.kt, examples/android/.../RagViewModel.kt, examples/flutter/.../rag_demo_view.dart, examples/flutter/.../rag_view_model.dart, examples/react-native/.../RAGScreen.tsx
Android, Flutter, and React Native screens add rerank and multi-query toggles, and their view models pass the settings into pipeline creation and query execution.
Add RAG tests, sample data, and build wiring
sdk/runanywhere-commons/tests/*
New SHA-256, fusion, rerank, and end-to-end RAG tests are added, along with a sample markdown corpus and CTest targets for the new executables.

React Native Package Build Script

Layer / File(s) Summary
Add package build script
sdk/runanywhere-react-native/packages/core/package.json
The package scripts section now includes a build command that runs tsc -b.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and clearly describes real parts of the change, even though it omits the larger RAG work.
Description check ✅ Passed The description follows the template closely and includes summary, change type, testing, labels, checklist, and screenshots.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch siddhesh/sdk-audit-fixes-v2

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🧹 Nitpick comments (2)
sdk/runanywhere-commons/src/features/rag/rag_backend.cpp (1)

670-691: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Redundant 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 | 🔵 Trivial

Missing upper bound on multi_query_count.

rac_min = 1 is declared but there's no rac_max. Combined with rac_rag_proto_abi.cpp passing this value through unclamped (see comment there), a caller can request an arbitrarily large fan-out of query rewrites/retrievals. Consider adding a rac_max annotation here for documentation/codegen parity with RAGConfiguration.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

📥 Commits

Reviewing files that changed from the base of the PR and between 4984216 and 1bcb98b.

⛔ Files ignored due to path filters (11)
  • sdk/runanywhere-commons/src/generated/proto/rag.pb.cc is excluded by !**/generated/**
  • sdk/runanywhere-commons/src/generated/proto/rag.pb.h is excluded by !**/generated/**
  • sdk/runanywhere-flutter/packages/runanywhere/lib/generated/convenience/ra_convenience.dart is excluded by !**/generated/**
  • sdk/runanywhere-flutter/packages/runanywhere/lib/generated/rag.pb.dart is excluded by !**/generated/**
  • sdk/runanywhere-kotlin/src/main/kotlin/com/runanywhere/sdk/generated/ai/runanywhere/proto/v1/RAGConfiguration.kt is excluded by !**/generated/**
  • sdk/runanywhere-kotlin/src/main/kotlin/com/runanywhere/sdk/generated/ai/runanywhere/proto/v1/RAGQueryOptions.kt is excluded by !**/generated/**
  • sdk/runanywhere-kotlin/src/main/kotlin/com/runanywhere/sdk/generated/convenience/RAConvenience.kt is excluded by !**/generated/**
  • sdk/shared/proto-ts/dist/convenience/rag_convenience.d.ts is excluded by !**/dist/**
  • sdk/shared/proto-ts/dist/convenience/rag_convenience.js is excluded by !**/dist/**
  • sdk/shared/proto-ts/dist/rag.d.ts is excluded by !**/dist/**
  • sdk/shared/proto-ts/dist/rag.js is excluded by !**/dist/**
📒 Files selected for processing (31)
  • examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/ui/screens/rag/RagScreen.kt
  • examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/ui/screens/rag/RagViewModel.kt
  • examples/flutter/RunAnywhereAI/lib/features/rag/rag_demo_view.dart
  • examples/flutter/RunAnywhereAI/lib/features/rag/rag_view_model.dart
  • examples/react-native/RunAnywhereAI/src/screens/RAGScreen.tsx
  • idl/rag.proto
  • sdk/runanywhere-commons/AGENTS.md
  • sdk/runanywhere-commons/CMakeLists.txt
  • sdk/runanywhere-commons/include/rac/foundation/rac_sha256.h
  • sdk/runanywhere-commons/src/features/rag/CMakeLists.txt
  • sdk/runanywhere-commons/src/features/rag/rac_rag_proto_abi.cpp
  • sdk/runanywhere-commons/src/features/rag/rag_backend.cpp
  • sdk/runanywhere-commons/src/features/rag/rag_backend.h
  • sdk/runanywhere-commons/src/features/rag/rag_fusion.cpp
  • sdk/runanywhere-commons/src/features/rag/rag_fusion.h
  • sdk/runanywhere-commons/src/features/rag/rag_pipeline_graph.cpp
  • sdk/runanywhere-commons/src/features/rag/rag_pipeline_graph.h
  • sdk/runanywhere-commons/src/features/rag/rag_rerank.cpp
  • sdk/runanywhere-commons/src/features/rag/rag_rerank.h
  • sdk/runanywhere-commons/src/features/rag/vector_store_usearch.cpp
  • sdk/runanywhere-commons/src/features/rag/vector_store_usearch.h
  • sdk/runanywhere-commons/src/foundation/rac_sha256.cpp
  • sdk/runanywhere-commons/src/infrastructure/http/rac_http_download.cpp
  • sdk/runanywhere-commons/tests/CMakeLists.txt
  • sdk/runanywhere-commons/tests/data/rag_sample.md
  • sdk/runanywhere-commons/tests/test_rag_e2e.cpp
  • sdk/runanywhere-commons/tests/test_rag_fusion.cpp
  • sdk/runanywhere-commons/tests/test_rag_rerank.cpp
  • sdk/runanywhere-commons/tests/test_sha256.cpp
  • sdk/shared/proto-ts/src/convenience/rag_convenience.ts
  • sdk/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

Comment thread examples/flutter/RunAnywhereAI/lib/features/rag/rag_view_model.dart
Comment thread examples/react-native/RunAnywhereAI/src/screens/RAGScreen.tsx
Comment thread sdk/runanywhere-commons/src/features/rag/rac_rag_proto_abi.cpp
Comment thread sdk/runanywhere-commons/src/features/rag/rag_backend.cpp
Comment thread sdk/runanywhere-commons/src/features/rag/rag_backend.cpp Outdated
Comment thread sdk/runanywhere-commons/src/features/rag/rag_fusion.cpp
Comment on lines +332 to +345
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);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '280,390p' sdk/runanywhere-commons/src/features/rag/vector_store_usearch.cpp

Repository: 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.cpp

Repository: 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.cpp

Repository: 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.

Comment thread sdk/runanywhere-commons/tests/test_rag_e2e.cpp
Comment thread sdk/shared/proto-ts/src/convenience/rag_convenience.ts Outdated
Siddhesh2377 and others added 24 commits July 7, 2026 06:24
…larity floor, fix clear() crash, single-document demos
…); drop removed GENIE/METALRT enum cases (flutter)
- 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.
Comment on lines +66 to +70
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, '')
sanchitmonga22 and others added 15 commits July 8, 2026 21:03
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.
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants