Skip to content

Conversation

@sanchitmonga22
Copy link
Contributor

@sanchitmonga22 sanchitmonga22 commented Dec 20, 2025

… files

  • Introduced a new .yarnrc.yml file to set the node linker to node-modules.
  • Updated yarn.lock to reflect new dependency versions.
  • Removed obsolete example files: streaming-llm-example.ts and TTSExample.ts, which are no longer needed.
  • Added new Core and Feature modules for improved functionality and organization.
  • Refactored various components and services to enhance maintainability and performance.

Description

Brief description of the changes made.

Type of Change

  • Bug fix
  • New feature
  • Documentation update
  • Refactoring

Testing

  • Tests pass locally
  • Tested on Macbook if swift changes
  • Tested on Tablet/iPad if swift changes
  • Added/updated tests for changes

Labels

Please add the appropriate label(s):

  • iOS SDK - Changes to iOS/Swift SDK
  • Android SDK - Changes to Android/Kotlin SDK
  • iOS Sample - Changes to iOS example app
  • Android Sample - Changes to Android example app

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Documentation updated (if needed)

Screenshots - Attach all the relevant UI changes screenshots for iOS/Android and MacOS/Tablet/large screen sizes

Greptile Summary

This PR implements a major architectural refactoring to align the React Native SDK with the iOS SDK structure. The changes introduce a clean separation of concerns following iOS patterns:

Major Changes:

  • Two-phase initialization: Phase 1 (sync, ~1-5ms) validates config and creates backend; Phase 2 (async, background) initializes services without blocking
  • New module structure: Organized into Core/, Features/, Foundation/, and Infrastructure/ matching iOS architecture
  • Unified lifecycle management: New ManagedLifecycle class handles model loading/unloading with integrated event tracking
  • Consolidated service registry: ServiceRegistry replaces separate ModuleRegistry and factory registries
  • Enhanced error handling: New Foundation/ErrorTypes/ with numeric error codes, categories, and context tracking (supports legacy string codes for backward compatibility)
  • Voice session support: New VoiceSessionHandle for React Native audio capture integration
  • Feature capabilities: Restructured LLMCapability, STTCapability, TTSCapability, VADCapability, and SpeakerDiarizationCapability with consistent patterns

Removed:

  • Obsolete example files (streaming-llm-example.ts, TTSExample.tsx)
  • Old routing and memory management services (moved to simplified architecture)
  • Legacy component implementations replaced by new capability system

Key Improvements:

  • Consistent iOS-aligned API surface
  • Better separation between core infrastructure and feature modules
  • Integrated analytics and telemetry tracking
  • Type-safe error handling with detailed context
  • Event-driven architecture with EventPublisher routing to both public EventBus and analytics

Issues Found:

  • Phase 2 initialization uses setTimeout which makes error handling non-deterministic - failures are logged but never surface to caller
  • Hardcoded version strings in multiple files instead of using SDKConstants.version
  • Device type detection defaults to 'phone' which will cause incorrect model assignments on tablets
  • Model registry state not persisted across app restarts

Confidence Score: 3/5

  • This PR is generally safe but requires attention to initialization error handling and hardcoded values before merging
  • The architectural refactoring is well-structured and follows iOS patterns correctly, but several issues impact production readiness: (1) Phase 2 initialization error handling is non-deterministic - errors are silently swallowed making debugging difficult, (2) hardcoded version strings will cause inaccurate telemetry, (3) device type detection always defaults to 'phone' causing incorrect model assignments on tablets, (4) the massive scope (287 files) increases risk of subtle breaking changes that may not surface until runtime
  • Pay close attention to src/Public/RunAnywhere.ts (initialization error handling), src/Infrastructure/Device/Services/DeviceRegistrationService.ts (version strings), and src/Infrastructure/ModelManagement/Services/ModelAssignmentService.ts (device type detection)

Important Files Changed

Filename Overview
sdk/runanywhere-react-native/src/Public/RunAnywhere.ts Major refactor implementing iOS-aligned two-phase initialization with background service loading and new capability architecture
sdk/runanywhere-react-native/src/Core/Capabilities/ManagedLifecycle.ts New lifecycle manager with integrated event tracking, properly separates concerns and follows iOS patterns
sdk/runanywhere-react-native/src/Foundation/DependencyInjection/ServiceRegistry.ts Unified registry consolidating previous ModuleRegistry and ServiceRegistry into single source of truth
sdk/runanywhere-react-native/src/Features/LLM/LLMCapability.ts Actor-based LLM capability using ManagedLifecycle for unified lifecycle management with analytics
sdk/runanywhere-react-native/src/Foundation/ErrorTypes/SDKError.ts Unified error system supporting both legacy string codes and new numeric codes for backward compatibility
sdk/runanywhere-react-native/src/index.ts Restructured exports matching iOS SDK architecture with comprehensive Foundation, Core, Infrastructure, and Features modules

Sequence Diagram

sequenceDiagram
    participant App as Application
    participant SDK as RunAnywhere SDK
    participant Core as Core/Foundation
    participant Services as ServiceRegistry
    participant Lifecycle as ManagedLifecycle
    participant Feature as LLM/STT/TTS Capability
    participant Provider as Framework Provider
    participant Native as Native Module
    
    Note over App,Native: Two-Phase Initialization
    
    App->>SDK: initialize(options)
    activate SDK
    
    Note over SDK,Core: Phase 1: Core (Sync, ~1-5ms)
    SDK->>Core: Validate config
    SDK->>Native: createBackend('llamacpp')
    Native-->>SDK: Backend created
    SDK->>Native: initialize(config)
    Native-->>SDK: Initialized
    SDK->>SDK: markCoreInitialized()
    SDK-->>App: isSDKInitialized = true
    
    Note over SDK,Services: Phase 2: Services (Async, ~100-500ms)
    SDK->>SDK: _startPhase2InBackground()
    deactivate SDK
    
    par Background Initialization
        SDK->>Services: registerProviders()
        Services->>Provider: LlamaCppProvider.register()
        Services->>Provider: ONNXProvider.register()
        SDK->>Services: ModelRegistry.initialize()
        SDK->>SDK: markServicesInitialized()
    end
    
    Note over App,Native: Model Loading & Generation
    
    App->>SDK: loadModel(modelId)
    SDK->>Feature: LLMCapability.loadModel()
    activate Feature
    Feature->>Lifecycle: load(modelId)
    activate Lifecycle
    Lifecycle->>Lifecycle: Emit loadStarted event
    Lifecycle->>Services: llmProvider(modelId)
    Services-->>Lifecycle: Provider instance
    Lifecycle->>Provider: createLLMService(config)
    Provider->>Native: Create native service
    Native-->>Provider: Service handle
    Provider-->>Lifecycle: LLMService
    Lifecycle->>Lifecycle: Emit loadCompleted event
    Lifecycle-->>Feature: Service loaded
    deactivate Lifecycle
    Feature-->>SDK: Model loaded
    deactivate Feature
    
    App->>SDK: generate(prompt, options)
    SDK->>Feature: LLMCapability.generate()
    activate Feature
    Feature->>Provider: service.generate()
    Provider->>Native: native.generate()
    Native-->>Provider: Result
    Provider-->>Feature: GenerationResult
    Feature->>Feature: Track analytics metrics
    Feature->>Lifecycle: Emit generation event
    Feature-->>SDK: Result with metrics
    deactivate Feature
    SDK-->>App: GenerationResult
    
    Note over App,Native: Cleanup
    
    App->>SDK: unloadModel()
    SDK->>Feature: unloadModel()
    Feature->>Lifecycle: unload()
    activate Lifecycle
    Lifecycle->>Lifecycle: Emit unloaded event
    Lifecycle->>Provider: service.cleanup()
    Provider->>Native: Release resources
    Lifecycle-->>Feature: Unloaded
    deactivate Lifecycle
    Feature-->>SDK: Success
    SDK-->>App: Success
Loading

Summary by CodeRabbit

  • New Features

    • Added API client and authentication services for backend communication.
    • Enhanced device capability detection with hardware acceleration and processor type identification.
    • Introduced lifecycle event tracking for model operations.
    • Added data persistence layer with repository and sync protocols.
  • Chores

    • Restructured SDK architecture with improved capability management.
    • Added comprehensive linting and code analysis tooling.
    • Expanded peer dependencies for enhanced platform support.

✏️ Tip: You can customize this high-level summary in your review settings.

… files

- Introduced a new .yarnrc.yml file to set the node linker to node-modules.
- Updated yarn.lock to reflect new dependency versions.
- Removed obsolete example files: streaming-llm-example.ts and TTSExample.ts, which are no longer needed.
- Added new Core and Feature modules for improved functionality and organization.
- Refactored various components and services to enhance maintainability and performance.
@coderabbitai
Copy link

coderabbitai bot commented Dec 20, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This PR restructures the React Native SDK's architecture by removing deprecated memory management and routing subsystems, introducing a capability-based lifecycle framework with integrated analytics, and establishing network, authentication, and data repository infrastructure for server synchronization.

Changes

Cohort / File(s) Summary
Configuration & Build Setup
sdk/runanywhere-react-native/.yarnrc.yml, package.json, knip.json, scripts/check_todos.js, scripts/run_analysis.js
Added Yarn config, expanded ESLint/TypeScript tooling, added peer dependencies (react-native-fs, react-native-blob-util, react-native-device-info, react-native-zip-archive), introduced KNIP unused-code detection, and added CI scripts for TODO validation and multi-tool analysis reporting.
Removed Examples & Legacy Code
examples/TTSExample.tsx, examples/streaming-llm-example.ts
Deleted TTS and streaming LLM example files.
New Core Capability Architecture
src/Core/Capabilities/CapabilityProtocols.ts, src/Core/Capabilities/ResourceTypes.ts, src/Core/Capabilities/ModelLifecycleManager.ts, src/Core/Capabilities/ManagedLifecycle.ts, src/Core/Capabilities/LifecycleEvents.ts, src/Core/Capabilities/Analytics/CoreAnalyticsTypes.ts, src/Core/Capabilities/Analytics/index.ts, src/Core/Capabilities/index.ts
Introduced unified capability protocols, resource type definitions, model lifecycle management, managed lifecycle wrappers with event publishing, and analytics metric tracking for LLM/STT/TTS/VAD/SpeakerDiarization.
Memory Management Removal
src/Capabilities/Memory/Services/AllocationManager.ts, src/Capabilities/Memory/Services/CacheEviction.ts, src/Capabilities/Memory/Services/MemoryMonitor.ts, src/Capabilities/Memory/Services/MemoryService.ts, src/Capabilities/Memory/Services/PressureHandler.ts
Removed entire memory subsystem (allocation, cache eviction, monitoring, pressure handling).
Text Generation Services Removal
src/Capabilities/TextGeneration/Services/GenerationService.ts, src/Capabilities/TextGeneration/Services/GenerationOptionsResolver.ts, src/Capabilities/TextGeneration/Services/StreamingService.ts, src/Capabilities/TextGeneration/Services/ThinkingParser.ts, src/Capabilities/TextGeneration/Services/TokenCounter.ts
Deleted legacy generation, streaming, thinking parsing, and token-counting services.
Model Loading & Routing Removal
src/Capabilities/ModelLoading/Models/LoadedModel.ts, src/Capabilities/ModelLoading/Services/ModelLoadingService.ts, src/Capabilities/Routing/Models/ExecutionTarget.ts, src/Capabilities/Routing/Models/RoutingDecision.ts, src/Capabilities/Routing/Models/RoutingReason.ts, src/Capabilities/Routing/Services/CostCalculator.ts, src/Capabilities/Routing/Services/ResourceChecker.ts, src/Capabilities/Routing/Services/RoutingService.ts
Removed model loading service and entire routing subsystem (execution targets, decisions, cost/resource checks).
Hardware Capability Updates
src/Capabilities/DeviceCapability/Services/HardwareCapabilityManager.ts, src/Capabilities/DeviceCapability/Models/DeviceCapabilities.ts
Enhanced HardwareCapabilityManager with react-native-device-info integration, device identifier caching, async capability fetching, NPU detection, and resource availability checks; minor formatting in DeviceCapabilities.
Registry & Model Discovery
src/Capabilities/Registry/Services/RegistryService.ts
Added model discovery and reconciliation, persistent registration, and richer query APIs (discoverModels, registerModel, filterModels, updateModel, removeModel).
Structured Output Updates
src/Capabilities/StructuredOutput/Services/StructuredOutputHandler.ts, src/Capabilities/StructuredOutput/Services/index.ts
Introduced GeneratableType interface, updated StructuredOutputConfig to use it, added StructuredOutputValidation interface and StructuredOutputError enum with new error variants, added parseStructuredOutput method; removed re-export.
Text Generation Models Updates
src/Capabilities/TextGeneration/Models/GenerationOptions.ts, src/Capabilities/TextGeneration/Models/GenerationResult.ts, src/Capabilities/TextGeneration/Models/InferenceRequest.ts, src/Capabilities/TextGeneration/Models/PerformanceMetrics.ts, src/Capabilities/TextGeneration/Models/index.ts
Re-exported ExecutionTarget/HardwareAcceleration from external enums, switched to type-only imports, removed InferenceRequest interface/class, and removed index re-exports.
Network & Authentication Infrastructure
src/Data/Network/APIEndpoint.ts, src/Data/Network/Models/AuthModels.ts, src/Data/Network/Services/APIClient.ts, src/Data/Network/Services/AuthenticationService.ts, src/Data/Network/Services/NetworkService.ts, src/Data/Network/index.ts
Added endpoint definitions, authentication/device registration models, APIClient with bearer token/header handling, AuthenticationService with token lifecycle and secure storage, and network service endpoint union support.
Data Layer Protocols & Repositories
src/Data/Protocols/DataSource.ts, src/Data/Protocols/Repository.ts, src/Data/Protocols/RepositoryEntity.ts, src/Data/Protocols/RepositoryError.ts, src/Data/Protocols/index.ts, src/Data/Repositories/ModelInfoRepository.ts, src/Data/Repositories/index.ts, src/Data/Services/ModelInfoService.ts, src/Data/Services/index.ts
Introduced data source/repository abstraction layers, syncable entities, repository error handling, model info repository with type-only imports, and service wrappers.
Data Sync Coordination
src/Data/Sync/SyncCoordinator.ts, src/Data/Sync/index.ts
Updated SyncCoordinator to use generic RepositoryEntity and SyncableRepository, added markSynced call post-sync.
Data Model Updates
src/Data/Models/Downloading/DownloadProgress.ts, src/Data/Models/Downloading/DownloadState.ts, src/Data/Models/Downloading/DownloadTask.ts
Removed download-related models (progress, state, task).
Core Models & Type System
src/Core/Models/Common/RequestPriority.ts, src/Core/Models/Common/ResourceAvailability.ts, src/Core/Models/Common/SDKComponent.ts, src/Core/Models/Common/TelemetryEventType.ts, src/Core/Models/Configuration/LLMConfiguration.ts, src/Core/Models/Configuration/STTConfiguration.ts, src/Core/Models/Configuration/SpeakerDiarizationConfiguration.ts, src/Core/Models/Configuration/TTSConfiguration.ts, src/Core/Models/Configuration/VLMConfiguration.ts, src/Core/Models/Configuration/WakeWordConfiguration.ts
Removed RequestPriority enum, TelemetryEventType enum, and placeholder configuration interfaces (LLM, STT, VLM, Wake Word, SpeakerDiarization); switched TTSConfiguration import to type-only; updated SDKComponent display names and removed VLM/Wake Word support.
Core Model Framework & Catalog
src/Core/Models/Framework/FrameworkModality.ts, src/Core/Models/Framework/LLMFramework.ts, src/Core/Models/Model/ModelCategory.ts, src/Core/Models/Model/ModelFormat.ts, src/Core/Models/Model/ModelInfo.ts, src/Core/Models/Model/ModelInfoMetadata.ts, src/Core/Models/Model/index.ts, src/Core/Models/STT/STTTranscriptionResult.ts, src/Core/Models/TTS/TTSResult.ts, src/Core/Models/VLM/VLMResult.ts, src/Data/modelCatalog.ts
Reformatted function signatures, switched multiple imports to type-only, removed index re-exports, enhanced STT/TTS result models with timestamp/metadata support, removed VLM result models, and refactored formatting.
Core Protocols Removal
src/Core/Protocols/Component/Component.ts, src/Core/Protocols/Lifecycle/ModelLifecycleProtocol.ts, src/Core/Protocols/Memory/MemoryManager.ts, src/Core/Protocols/VLM/VLMService.ts, src/Core/Protocols/VLM/VLMServiceProvider.ts, src/Core/Protocols/Voice/WakeWordService.ts, src/Core/Protocols/Voice/WakeWordServiceProvider.ts
Deleted component protocol, model lifecycle protocol, memory manager protocol, VLM service protocols, and wake word service protocols.
Core Protocols Updates
src/Core/Protocols/LLM/LLMService.ts, src/Core/Protocols/LLM/LLMServiceProvider.ts, src/Core/Protocols/Memory/MemoryModels.ts, src/Core/Protocols/Registry/ModelRegistry.ts, src/Core/Protocols/Voice/STTService.ts, src/Core/Protocols/Voice/STTServiceProvider.ts, src/Core/Protocols/Voice/SpeakerDiarizationService.ts, src/Core/Protocols/Voice/SpeakerDiarizationServiceProvider.ts, src/Core/Protocols/Voice/TTSService.ts
Reformatted method signatures, switched to type-only imports, updated import paths for configuration types, added supportsStreaming property to STTService.
Core Module Registry Removal
src/Core/ModuleRegistry.ts
Removed ModuleRegistry class and provider registration system.
Core Components
src/Core/Components/BaseComponent.ts
Reformatted generic parameter to multi-line declaration.
LLM Feature Implementation
src/Features/LLM/Errors/LLMError.ts, src/Features/LLM/LLMCapability.ts, src/Features/LLM/LLMConfiguration.ts, src/Features/LLM/LLMModels.ts
Introduced LLMError with factory methods, renamed LLMComponent to LLMCapability with ManagedLifecycle integration and analytics tracking, updated configuration imports to type-only.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Areas requiring extra attention:

  • HardwareCapabilityManager async integration — Dynamic require for react-native-device-info with fallback handling, device identifier caching, NPU detection logic, and optional initialization patterns.
  • ManagedLifecycle & ModelLifecycleManager generics — New generic lifecycle framework; verify type safety, lifecycle state transitions, and event publishing coordination.
  • NetworkService & APIClient implementation — Bearer token handling, error parsing from multiple formats, timeout management, secure storage interaction assumptions.
  • SyncCoordinator generic refactoring — Changed from Repository to SyncableRepository; verify repository implementations conform to the new interface and markSynced semantics.
  • RegistryService model reconciliation — New local model discovery and merge-with-remote logic; verify deduplication and conflict resolution during initialization.
  • LLMCapability redesign — Renamed from LLMComponent; replaced direct service management with ManagedLifecycle and ServiceRegistry lookup; verify provider resolution and service lifecycle.
  • Removed subsystems — Large deletions (memory management, routing, legacy services); verify no orphaned dependencies or broken imports remain.
  • Type-only import conversions — Widespread changes from value to type-only imports; verify no runtime references are lost and TypeScript compilation succeeds.

Possibly related PRs

Suggested labels

react-native-sdk, architecture-refactor, lifecycle-management, data-layer, network-integration

Poem

🐰 Hops through the SDK, a rabbit so spry,
Old memory walls crumble, new capabilities fly,
With lifecycle events and repos so neat,
The network now flows, the sync is complete!
Goodbye routing and routing, hello clean design,
This React Native future? It's simply divine!

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description includes multiple completed sections: bullet points covering technical changes, a structured description of modifications, and comprehensive Greptile analysis. However, the template sections (Type of Change, Testing, Labels, Checklist) remain unchecked, indicating incomplete pre-merge documentation. Complete the template by checking appropriate boxes for Type of Change (Refactoring), Testing status, Labels, and project Checklist to fully satisfy documentation requirements before merge.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'React-native alignment with iOS' accurately reflects the primary objective of aligning the React Native SDK with iOS SDK architecture, as detailed in the PR objectives.
Docstring Coverage ✅ Passed Docstring coverage is 90.41% which is sufficient. The required threshold is 80.00%.

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 and usage tips.

@sanchitmonga22 sanchitmonga22 changed the title Add Yarn configuration and update dependencies; remove unused example… React-native alignment with iOS Dec 20, 2025
…and update TypeScript settings

- Introduced new linting reports for ESLint and TypeScript, enhancing code quality checks.
- Added configuration files for knip and updated TypeScript settings to exclude test files.
- Created scripts for checking todos and running analysis, improving development workflow.
- Updated package.json and yarn.lock to reflect new dependencies and configurations.
- Removed obsolete files and refactored existing services for better organization and maintainability.
…ndling and type safety

- Updated MemoryMonitor to handle null entries in recent history and memory entries, enhancing robustness.
- Refactored various services to replace 'any' types with more specific types, improving type safety.
- Enhanced logging in ManagedLifecycle and ModelLifecycleManager to utilize SDKLogger for consistent logging practices.
- Removed obsolete configuration files related to LLM and SpeakerDiarization, streamlining the codebase.
- Improved event handling in EventBus to prevent potential runtime errors when accessing subscribers.
…functionality

- Added optional peer dependencies: react-native-fs, react-native-blob-util, react-native-device-info, and react-native-zip-archive to support enhanced file and device management.
- Refactored HardwareCapabilityManager to utilize react-native-device-info for better device capability detection.
- Updated DownloadService to leverage react-native-blob-util and react-native-fs for improved download management and file operations.
- Removed obsolete memory management services to streamline the codebase and improve maintainability.
- Enhanced STT and TTS capabilities with updated data structures and improved handling of transcription results.
- Removed legacy SDKError exports and restructured error handling to improve clarity and maintainability.
- Introduced AuthenticationService for managing device registration and token management, aligning with iOS SDK functionality.
- Added DeviceRegistrationService for handling device registration with backend, including fallback storage options.
- Implemented ModelAssignmentService for fetching and managing model assignments from the backend, enhancing model management capabilities.
- Updated logging infrastructure to support centralized logging with multiple destinations.
- Refactored LLM capabilities to include generation metrics and analytics tracking for improved performance insights.
- Streamlined the ServiceContainer to manage new services and dependencies effectively.
…structure

- Deleted LoadedModel, ModelLoadingService, ExecutionTarget, RoutingDecision, RoutingReason, CostCalculator, ResourceChecker, RoutingService, GenerationOptionsResolver, GenerationService, StreamingService, ThinkingParser, TokenCounter, and related files to enhance maintainability.
- Refactored imports and dependencies across the SDK to reflect the removal of these services.
- Improved overall code organization by eliminating unused components and consolidating functionality.
- Added structured output generation features, including Generatable protocol and JSON schema utilities for LLM responses.
- Introduced new data protocols and repositories for improved data management, including DataSource and RepositoryEntity.
- Implemented error handling for STT and TTS operations, enhancing robustness with typed error classes.
- Refactored existing modules to streamline imports and improve organization, ensuring better maintainability.
- Updated enums to include new audio formats and associated utility functions for file handling.
- Introduced Voice Session module for high-level voice assistant integration, including event handling and configuration options.
- Added Speaker Diarization error handling with specific error codes and classes for improved robustness.
- Updated SDK structure to include new VoiceSession and SpeakerDiarization features, enhancing overall functionality.
- Refactored existing imports to streamline access to new modules and improve organization.
@sanchitmonga22
Copy link
Contributor Author

@coderabbitai please do a detailed review

@sanchitmonga22
Copy link
Contributor Author

@greptile please do a detailed review

@coderabbitai
Copy link

coderabbitai bot commented Dec 21, 2025

@sanchitmonga22: I'll perform a detailed review of the changes in this PR.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

286 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

Comment on lines 530 to 540
setTimeout(async () => {
try {
await this.completeServicesInitialization();
logger.info('Phase 2 complete (background)');
} catch (error) {
// Phase 2 failure is non-critical
const errorMessage =
error instanceof Error ? error.message : String(error);
logger.warning(`Phase 2 failed (non-critical): ${errorMessage}`);
}
}, 0);
Copy link

Choose a reason for hiding this comment

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

logic: using setTimeout(..., 0) to defer Phase 2 makes error handling non-deterministic. If Phase 2 fails, the error is only logged but never surfaces to the caller. This creates a silent failure mode where areServicesReady stays false indefinitely.

consider returning a Promise that tracks Phase 2 completion, allowing callers to optionally await it if they need guarantees about service readiness.

Prompt To Fix With AI
This is a comment left during a code review.
Path: sdk/runanywhere-react-native/src/Public/RunAnywhere.ts
Line: 530:540

Comment:
**logic:** using `setTimeout(..., 0)` to defer Phase 2 makes error handling non-deterministic. If Phase 2 fails, the error is only logged but never surfaces to the caller. This creates a silent failure mode where `areServicesReady` stays false indefinitely.

consider returning a Promise that tracks Phase 2 completion, allowing callers to optionally await it if they need guarantees about service readiness.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 239 to 240
appVersion: '1.0.0', // TODO: Get from app config
sdkVersion: '0.1.0', // TODO: Get from SDK version
Copy link

Choose a reason for hiding this comment

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

logic: hardcoded version values will cause analytics/telemetry data to be inaccurate

Prompt To Fix With AI
This is a comment left during a code review.
Path: sdk/runanywhere-react-native/src/Infrastructure/Device/Services/DeviceRegistrationService.ts
Line: 239:240

Comment:
**logic:** hardcoded version values will cause analytics/telemetry data to be inaccurate

How can I resolve this? If you propose a fix, please make it concise.

const { requireDeviceInfoModule } = await import('../../../native');
const deviceInfo = requireDeviceInfoModule();
platform = (await deviceInfo.getPlatform?.()) ?? 'ios';
deviceType = 'phone'; // TODO: Detect phone vs tablet
Copy link

Choose a reason for hiding this comment

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

logic: defaulting all devices to 'phone' will cause incorrect model assignments for tablet devices with more capable hardware

Prompt To Fix With AI
This is a comment left during a code review.
Path: sdk/runanywhere-react-native/src/Infrastructure/ModelManagement/Services/ModelAssignmentService.ts
Line: 201:201

Comment:
**logic:** defaulting all devices to 'phone' will cause incorrect model assignments for tablet devices with more capable hardware

How can I resolve this? If you propose a fix, please make it concise.

api_key: apiKey,
device_id: deviceId,
platform: 'react-native',
sdk_version: '0.1.0', // TODO: Get from version file
Copy link

Choose a reason for hiding this comment

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

style: hardcoded SDK version should be imported from SDKConstants.version

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: sdk/runanywhere-react-native/src/Data/Network/Services/AuthenticationService.ts
Line: 157:157

Comment:
**style:** hardcoded SDK version should be imported from `SDKConstants.version`

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

- Removed unused error exports and consolidated error handling for STT, TTS, and VAD features to improve clarity and maintainability.
- Updated import statements for better organization and consistency across modules.
- Enhanced error classes with improved formatting for better readability.
- Deleted obsolete files related to error handling to streamline the codebase.
@sanchitmonga22
Copy link
Contributor Author

@coderabbitai please do a full review of the PR

@coderabbitai
Copy link

coderabbitai bot commented Dec 21, 2025

@sanchitmonga22: I'll perform a full review of all the changes in this PR.

✅ Actions performed

Full review triggered.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 14

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
sdk/runanywhere-react-native/src/Core/Models/Common/SDKComponent.ts (1)

39-51: Non-exhaustive switch causes undefined return for VLM and WakeWord.

The componentRequiresModel function has the same issue as getComponentDisplayName: it no longer handles SDKComponent.VLM and SDKComponent.WakeWord, returning undefined instead of a boolean. This can cause logical errors in conditionals where a boolean is expected.

🔎 Proposed fix: Add explicit handling or default case
 export function componentRequiresModel(component: SDKComponent): boolean {
   switch (component) {
     case SDKComponent.LLM:
     case SDKComponent.STT:
     case SDKComponent.Embedding:
       return true;
     case SDKComponent.TTS:
     case SDKComponent.VAD:
     case SDKComponent.SpeakerDiarization:
     case SDKComponent.VoiceAgent:
       return false;
+    case SDKComponent.VLM:
+    case SDKComponent.WakeWord:
+      return false; // or true, depending on whether these components require models
   }
 }

Alternatively, add a default case that returns false or throws an error for unsupported components.

sdk/runanywhere-react-native/src/Capabilities/Registry/Services/RegistryService.ts (1)

82-98: registerModelPersistently doesn't actually persist.

The persistence logic is entirely commented out, making this method functionally identical to registerModel. Either implement the persistence or remove this method to avoid misleading API consumers.

♻️ Duplicate comments (1)
sdk/runanywhere-react-native/src/Data/Network/Services/AuthenticationService.ts (1)

153-158: Hardcoded SDK version should use SDKConstants.version.

This issue was already flagged in a previous review. The sdk_version should be imported from SDKConstants.version instead of being hardcoded.

🟡 Minor comments (7)
sdk/runanywhere-react-native/src/Core/Models/STT/STTTranscriptionResult.ts-34-45 (1)

34-45: Document confidence range.

The confidence field should document its expected range for consistency with the other interfaces (0.0-1.0).

🔎 Suggested documentation enhancement
 export interface STTTranscriptionResult {
   /** The transcribed text */
   transcript: string;
-  /** Confidence score for the transcription (optional) */
+  /** Confidence score for the transcription, range 0.0-1.0 (optional) */
   confidence?: number;
   /** Word-level timestamp information (optional) */
   timestamps?: TimestampInfo[];
   /** Detected language (optional) */
   language?: string;
   /** Alternative transcriptions (optional) */
   alternatives?: AlternativeTranscription[];
 }
sdk/runanywhere-react-native/scripts/run_analysis.js-34-42 (1)

34-42: Missing stderr capture on command failure.

When execSync throws, error messages may be in error.stderr rather than error.stdout. The current code only captures error.stdout || error.message, potentially losing diagnostic output.

🔎 Proposed fix
   } catch (error) {
-    const output = error.stdout || error.message;
+    const output = [error.stdout, error.stderr, error.message]
+      .filter(Boolean)
+      .join('\n');
     fs.writeFileSync(outputFile, output);
sdk/runanywhere-react-native/src/Capabilities/DeviceCapability/Services/HardwareCapabilityManager.ts-432-442 (1)

432-442: Unreliable Android NPU detection.

Checking for chipset names in the model string is unreliable:

  1. Many devices don't include chipset names in their model identifier
  2. Not all Snapdragon/Exynos chips have NPUs (older generations lack them)
  3. A Samsung "Galaxy S23" won't have "Snapdragon" or "Exynos" in its model name

Consider defaulting Android NPU to false or using a known-device lookup table for high-confidence detection.

🔎 Proposed conservative approach
     if (Platform.OS === 'android') {
-      // Check for known NPU-capable chips
-      const deviceLower = (model + deviceId).toLowerCase();
-      return (
-        deviceLower.includes('snapdragon') ||
-        deviceLower.includes('exynos') ||
-        deviceLower.includes('tensor') ||
-        deviceLower.includes('dimensity') ||
-        deviceLower.includes('kirin')
-      );
+      // NPU detection on Android is unreliable without native APIs
+      // Default to false; GPU acceleration is still available
+      return false;
     }
sdk/runanywhere-react-native/src/Capabilities/DeviceCapability/Services/HardwareCapabilityManager.ts-67-95 (1)

67-95: Inconsistent fallback values for device identifier.

The sync getter returns 'Unknown-ReactNative' when _deviceIdentifier is null (line 68), but fetchDeviceIdentifier sets ${Platform.OS}-Unknown when DeviceInfo is unavailable (line 89). This inconsistency could cause unexpected behavior if code compares identifiers.

🔎 Proposed fix
       } else {
-        this._deviceIdentifier = `${Platform.OS}-Unknown`;
+        this._deviceIdentifier = 'Unknown-ReactNative';
       }

Or update the sync getter to match:

   public get deviceIdentifier(): string {
-    return this._deviceIdentifier ?? 'Unknown-ReactNative';
+    return this._deviceIdentifier ?? `${Platform.OS}-Unknown`;
   }
sdk/runanywhere-react-native/src/Capabilities/Registry/Services/RegistryService.ts-32-32 (1)

32-32: Unused _apiKey parameter.

The initialize method accepts _apiKey but never uses it. If the API key is needed for model discovery or remote fetching, it should be utilized; otherwise, consider removing the parameter.

sdk/runanywhere-react-native/src/Core/Capabilities/ModelLifecycleManager.ts-137-145 (1)

137-145: loadingState('') passes empty string instead of the resourceId being loaded.

When a load is in progress, loadingState('') should ideally pass the resourceId currently being loaded. However, since inflightPromise doesn't track which resource is being loaded, you may need to add a field like loadingResourceId to track this.

🔎 Suggested approach
  private service: TService | null = null;
  private loadedResourceId: string | null = null;
+ private loadingResourceId: string | null = null;
  private inflightPromise: Promise<TService> | null = null;

Then update the state getter and load method accordingly.

Committable suggestion skipped: line range outside the PR's diff.

sdk/runanywhere-react-native/src/Capabilities/StructuredOutput/Services/StructuredOutputHandler.ts-312-326 (1)

312-326: Unused schema parameter in parseStructuredOutput

The schema: GeneratableType parameter is accepted but never used for validation. The method only extracts and parses JSON without validating against the provided schema. This could lead to runtime errors if the parsed JSON doesn't conform to the expected type T.

Consider either:

  1. Implementing actual schema validation using the jsonSchema property
  2. Removing the unused parameter and documenting that validation is the caller's responsibility
🔎 If validation is intended to be caller's responsibility
-  public parseStructuredOutput<T>(text: string, schema: GeneratableType): T {
+  /**
+   * Parse JSON from generated text. Note: Does not validate against schema.
+   * Caller should validate the returned object matches expected type.
+   */
+  public parseStructuredOutput<T>(text: string, _schema?: GeneratableType): T {
🧹 Nitpick comments (29)
sdk/runanywhere-react-native/src/Core/Models/TTS/TTSResult.ts (1)

60-63: Base64 size approximation ignores padding characters.

The * 0.75 factor doesn't account for base64 padding (= characters), which can cause the result to be slightly over-estimated (by up to 2 bytes). This is likely acceptable for most use cases, but if precision matters, consider accounting for padding.

🔎 More accurate calculation
 export function getTTSResultAudioSizeBytes(result: TTSResult): number {
-  // Base64 to raw bytes: base64 length * 3/4
-  return Math.floor(result.audioData.length * 0.75);
+  // Base64 to raw bytes, accounting for padding
+  const padding = (result.audioData.match(/=$/g) || []).length;
+  return Math.floor((result.audioData.length * 3) / 4) - padding;
 }
sdk/runanywhere-react-native/src/Core/Models/STT/STTTranscriptionResult.ts (2)

9-18: Document confidence score range and consider time validation.

The confidence field lacks documentation about its expected range (e.g., 0.0-1.0). Additionally, there's no indication that startTime should be less than endTime, which could lead to invalid data if not validated upstream.

🔎 Suggested documentation enhancement
 export interface TimestampInfo {
   /** The word */
   word: string;
   /** Start time in seconds */
   startTime: number;
   /** End time in seconds */
   endTime: number;
-  /** Confidence score for this word (optional) */
+  /** Confidence score for this word, range 0.0-1.0 (optional) */
   confidence?: number;
 }

23-28: Document confidence score range.

Similar to TimestampInfo, the confidence field should document its expected range (e.g., 0.0-1.0 or 0-100).

🔎 Suggested documentation enhancement
 export interface AlternativeTranscription {
   /** The alternative transcript text */
   transcript: string;
-  /** Confidence score for this alternative */
+  /** Confidence score for this alternative, range 0.0-1.0 */
   confidence: number;
 }
sdk/runanywhere-react-native/src/Features/LLM/Errors/LLMError.ts (1)

162-167: ErrorCode.GenerationFailed is semantically inaccurate for service busy state.

The serviceBusy() method uses ErrorCode.GenerationFailed, which conflates "the service is currently processing another request" with "generation failed." No more appropriate error code exists in the enum. Consider adding a new error code (e.g., ErrorCode.ServiceBusy or ErrorCode.ServiceUnavailable) to the ErrorCode enum to better represent transient service unavailability.

sdk/runanywhere-react-native/knip.json (1)

6-20: Duplicate test exclusion patterns.

Test patterns are excluded in both project (lines 8-9) and ignore (lines 19-20). While this doesn't cause issues, it's redundant since exclusions in project already prevent those files from being analyzed.

🔎 Proposed simplification
   "ignore": [
     "lib/**",
     "nitrogen/**",
     "node_modules/**",
     "android/**",
     "ios/**",
     "cpp/**",
-    "example/**",
-    "src/__tests__/**",
-    "src/**/*.test.ts"
+    "example/**"
   ],
sdk/runanywhere-react-native/scripts/check_todos.js (1)

16-21: Redundant skip logic and misleading naming.

SKIP_DIRS includes .test.ts which is a file extension, not a directory (misleading name). Additionally, glob.sync at lines 50-51 already excludes these patterns via ignore, making the shouldSkip check at line 57 redundant.

🔎 Proposed simplification

Remove the redundant skip logic since glob already handles filtering:

-// Directories to skip
-const SKIP_DIRS = ['node_modules', '__tests__', '.test.ts'];
-
-function shouldSkip(filePath) {
-  return SKIP_DIRS.some(skip => filePath.includes(skip));
-}
-
 function checkFile(filePath) {
   files.forEach(file => {
-    if (!shouldSkip(file)) {
-      const issues = checkFile(file);
-      allIssues = allIssues.concat(issues);
-    }
+    const issues = checkFile(file);
+    allIssues = allIssues.concat(issues);
   });
sdk/runanywhere-react-native/src/Capabilities/DeviceCapability/Services/HardwareCapabilityManager.ts (2)

222-247: Consider model-aware acceleration selection.

The _model parameter is currently unused. For a more robust implementation, consider using ModelInfo properties (e.g., compatibleFrameworks, format) to select appropriate acceleration. Some model formats may not benefit from NPU acceleration.


333-352: Consider extracting magic numbers to named constants.

The hardcoded memory values (4GB, 2GB) could be extracted to named constants for better readability and maintainability:

private static readonly DEFAULT_TOTAL_MEMORY = 4_000_000_000;
private static readonly DEFAULT_AVAILABLE_MEMORY = 2_000_000_000;
sdk/runanywhere-react-native/src/Data/Protocols/RepositoryError.ts (2)

93-108: Duplicate method implementation.

The methods networkUnavailable() and networkNotAvailable() have identical implementations. Consider one of these approaches:

  • If both are needed for backwards compatibility, document this and have one delegate to the other
  • If this is unintentional duplication, remove one method
🔎 Proposed fix to eliminate duplication
  /**
   * Network unavailable for sync
   */
  static networkUnavailable(): RepositoryError {
    return new RepositoryError(
      ErrorCode.NetworkUnavailable,
      'Network unavailable for sync'
    );
  }

  /**
   * Network not available (alias)
   */
  static networkNotAvailable(): RepositoryError {
-    return new RepositoryError(
-      ErrorCode.NetworkUnavailable,
-      'Network unavailable for sync'
-    );
+    return this.networkUnavailable();
  }

18-65: Consider more specific error codes for distinct operations.

The saveFailure, fetchFailure, deleteFailure, and syncFailure methods all use ErrorCode.Unknown. If more specific error codes are available in the ErrorCode enum (e.g., DatabaseWriteError, DatabaseReadError), consider using them to improve error diagnostics and handling.

sdk/runanywhere-react-native/src/Core/Capabilities/ModelLifecycleManager.ts (1)

260-268: Inefficient logger instantiation on every log call.

Creating a new SDKLogger instance on each log() and logError() call is wasteful. Consider making the logger a class field initialized once in the constructor.

🔎 Proposed fix
  // MARK: - Dependencies

  private readonly category: string;
+ private readonly logger: SDKLogger;
  private readonly loadResourceFn: LoadResourceFn<TService>;
  private readonly unloadResourceFn: UnloadResourceFn<TService>;

  // MARK: - Initialization

  constructor(options: ModelLifecycleManagerOptions<TService>) {
    this.category = options.category;
+   this.logger = new SDKLogger(options.category);
    this.loadResourceFn = options.loadResource;
    this.unloadResourceFn = options.unloadResource;
  }

  // ...

  private log(message: string): void {
-   const logger = new SDKLogger(this.category);
-   logger.debug(message);
+   this.logger.debug(message);
  }

  private logError(message: string): void {
-   const logger = new SDKLogger(this.category);
-   logger.error(message);
+   this.logger.error(message);
  }
sdk/runanywhere-react-native/src/Data/Network/Services/APIClient.ts (1)

277-292: Duplicate error handling logic in postRaw and getRaw.

The catch block logic (lines 277-292 and 327-342) is nearly identical. Consider extracting to a private helper method.

🔎 Suggested extraction
private handleFetchError(error: unknown): never {
  if (error instanceof APIClientError) {
    throw error;
  }

  if ((error as Error).name === 'AbortError') {
    throw new APIClientError('Request timeout', 0);
  }

  throw new APIClientError(
    (error as Error).message ?? 'Network request failed',
    0
  );
}

Also applies to: 327-342

sdk/runanywhere-react-native/src/Core/Capabilities/ManagedLifecycle.ts (2)

483-507: Misleading comment in createModelEvent.

The comment says "Reuse generic model events for VAD/Diarization" but VAD and Diarization have their own dedicated event creators handled in createVADEvent and createSpeakerDiarizationEvent above. This fallback is for unknown/future resource types.

🔎 Suggested comment fix
  private createModelEvent(
    type: LifecycleEventType,
    resourceId: string,
    durationMs?: number,
    error?: Error
  ): SDKEvent {
-   // Reuse generic model events for VAD/Diarization
+   // Fallback to generic model events for unknown resource types
    switch (type) {

511-519: Same inefficient logger pattern as ModelLifecycleManager.

Consider making the logger a class field to avoid repeated instantiation, consistent with the suggested refactor in ModelLifecycleManager.ts.

sdk/runanywhere-react-native/src/Data/Protocols/DataSource.ts (1)

182-196: Timeout race leaks timers and doesn't abort the operation.

When the operation completes first, the setTimeout timer continues running until it fires. Additionally, if the timeout fires first, the underlying operation continues executing in the background.

Consider clearing the timer on completion and optionally supporting AbortSignal for cancellable operations.

🔎 Proposed fix with timer cleanup
 export class RemoteOperationHelper {
   constructor(private readonly timeout: number = 10000) {}

   async withTimeout<R>(operation: () => Promise<R>): Promise<R> {
-    return Promise.race([
-      operation(),
-      new Promise<R>((_, reject) =>
-        setTimeout(
-          () => reject(DataSourceError.networkUnavailable()),
-          this.timeout
-        )
-      ),
-    ]);
+    let timeoutId: ReturnType<typeof setTimeout>;
+    const timeoutPromise = new Promise<R>((_, reject) => {
+      timeoutId = setTimeout(
+        () => reject(DataSourceError.networkUnavailable()),
+        this.timeout
+      );
+    });
+    try {
+      return await Promise.race([operation(), timeoutPromise]);
+    } finally {
+      clearTimeout(timeoutId!);
+    }
   }
 }
sdk/runanywhere-react-native/src/Features/LLM/LLMCapability.ts (3)

508-510: Unused variable _modelId.

The variable is assigned but never used in generateStreamWithMetrics.

🔎 Proposed fix
    // Use managedLifecycle.requireService() for iOS parity
    const llmService = this.managedLifecycle.requireService();
-   const _modelId = this.managedLifecycle.resourceIdOrUnknown();

726-739: Unused variable _performanceMetrics.

PerformanceMetricsImpl is instantiated but never used or returned. If this is intentional scaffolding for future use, consider adding a TODO comment; otherwise, remove it.

🔎 Proposed fix (remove if unused)
    // Estimate prompt tokens (rough estimate: 1 token ≈ 4 characters)
    const promptTokens = Math.floor(collector.fullText.length / 4);
    const completionTokens = collector.tokenCount;

-   const _performanceMetrics = new PerformanceMetricsImpl({
-     tokenizationTimeMs: 0,
-     inferenceTimeMs: totalTimeMs,
-     postProcessingTimeMs: 0,
-     tokensPerSecond,
-     peakMemoryUsage: 0,
-     queueWaitTimeMs: 0,
-     timeToFirstTokenMs,
-     thinkingTimeMs: null,
-     responseTimeMs: totalTimeMs,
-   });
-
    return {

666-670: Simplify optional chaining with nullish check.

The shift() can return undefined on an empty array. The continue handles this correctly, but it's slightly more idiomatic to use a single guard.

🔎 Minor simplification
        if (tokenQueue.length > 0) {
-         const token = tokenQueue.shift();
-         if (!token) continue;
+         const token = tokenQueue.shift()!;
          yield token;

This is safe because the length > 0 check guarantees a value exists.

sdk/runanywhere-react-native/src/Core/Capabilities/ResourceTypes.ts (1)

29-46: Consider leveraging TypeScript exhaustiveness checking.

The implementation is correct, but you could make the switch statement exhaustive to catch missing cases at compile time if new enum members are added later.

🔎 Optional improvement for exhaustiveness
 export function getResourceTypeDisplayName(
   type: CapabilityResourceType
 ): string {
   switch (type) {
     case CapabilityResourceType.LLMModel:
       return 'LLM Model';
     case CapabilityResourceType.STTModel:
       return 'STT Model';
     case CapabilityResourceType.TTSVoice:
       return 'TTS Voice';
     case CapabilityResourceType.VADModel:
       return 'VAD Model';
     case CapabilityResourceType.DiarizationModel:
       return 'Diarization Model';
     default:
-      return 'Unknown Resource';
+      const _exhaustive: never = type;
+      return _exhaustive;
   }
 }

This pattern ensures that if a new enum member is added without updating the switch, TypeScript will emit a compile error.

sdk/runanywhere-react-native/src/Capabilities/StructuredOutput/Services/StructuredOutputHandler.ts (2)

14-19: Duplicate type definition: GeneratableType vs Generatable

This interface duplicates the Generatable interface defined in sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/Generatable.ts (lines 31-41 in relevant snippets show StructuredOutputConfig using Generatable). This creates two parallel type hierarchies for the same concept.

Consider consolidating these into a single type and re-exporting from a central location to avoid divergence.


332-350: Unused _config parameter in validateStructuredOutput

The _config parameter is marked as unused (underscore prefix) but the method could use config.type.jsonSchema to perform actual schema validation instead of just checking if JSON is extractable.

sdk/runanywhere-react-native/src/Data/Protocols/Repository.ts (1)

84-98: Sequential processing in markSynced may be slow for large batches

The current implementation processes each ID sequentially with individual fetch and save calls. For large sync batches, this could be slow due to the round-trip overhead of each operation.

Additionally, if one operation fails, the remaining entities won't be processed, leaving partial state.

🔎 Consider parallel processing with error collection
   async markSynced<Entity extends RepositoryEntity>(
     repository: Repository<Entity>,
     ids: string[]
   ): Promise<void> {
-    for (const id of ids) {
-      const entity = await repository.fetch(id);
-      if (entity) {
-        const updated = {
-          ...entity,
-          syncPending: false,
-        };
-        await repository.save(updated);
-      }
-    }
+    await Promise.all(
+      ids.map(async (id) => {
+        const entity = await repository.fetch(id);
+        if (entity) {
+          await repository.save({ ...entity, syncPending: false });
+        }
+      })
+    );
   },
sdk/runanywhere-react-native/src/Data/Network/Services/NetworkService.ts (1)

124-130: Generic error message loses response details

The error only includes response.statusText but not the status code or response body, making debugging difficult. Consider including more context.

🔎 Include status code in error
     if (!response.ok) {
-      throw new Error(`Network request failed: ${response.statusText}`);
+      throw new Error(`Network request failed: ${response.status} ${response.statusText}`);
     }
sdk/runanywhere-react-native/src/Data/Network/Models/AuthModels.ts (1)

166-177: Hardcoded SDK version should use SDKConstants.version.

The default sdkVersion parameter is hardcoded as '0.1.0'. This should import and use SDKConstants.version to ensure consistency across the codebase and avoid drift when the version is updated.

Proposed fix
+import { SDKConstants } from '../../../Foundation/Constants/SDKConstants';
+
 export function createAuthRequest(
   apiKey: string,
   deviceId: string,
-  sdkVersion: string = '0.1.0'
+  sdkVersion: string = SDKConstants.version
 ): AuthenticationRequest {
sdk/runanywhere-react-native/src/Data/Network/Services/AuthenticationService.ts (2)

75-75: Incomplete singleton pattern - _instance is never assigned.

The static _instance field is declared and reset() clears it, but createAndAuthenticate() never assigns the created instance to _instance. Either complete the singleton pattern or remove the unused field and reset() method.

Option 1: Complete the singleton pattern
   static async createAndAuthenticate(
     apiClient: APIClient,
     apiKey: string,
     environment: SDKEnvironment
   ): Promise<AuthenticationService> {
     const authService = new AuthenticationService(apiClient, environment);
+    AuthenticationService._instance = authService;

     // Wire up auth provider to API client
     apiClient.setAuthenticationProvider(authService);
Option 2: Remove unused singleton scaffolding
-  private static _instance: AuthenticationService | null = null;
   
   // ... at end of class ...
   
-  /**
-   * Reset the singleton (for testing)
-   */
-  static reset(): void {
-    AuthenticationService._instance = null;
-  }

Also applies to: 398-400


254-261: Add validation for parsed timestamp to guard against corrupted storage.

If expiresAt contains an invalid value, parseInt returns NaN, and new Date(NaN) produces an invalid date. Consider adding a validation check.

Proposed fix
-        tokenExpiresAt: expiresAt ? new Date(parseInt(expiresAt, 10)) : null,
+        tokenExpiresAt: expiresAt
+          ? (() => {
+              const ts = parseInt(expiresAt, 10);
+              return Number.isNaN(ts) ? null : new Date(ts);
+            })()
+          : null,
sdk/runanywhere-react-native/src/Core/Capabilities/CapabilityProtocols.ts (1)

265-327: Consider preserving the underlying error in the error chain.

The static factory methods accept an underlyingError parameter but only include its message in the error string. For better debugging, consider setting the cause property (ES2022+) or storing the underlying error as a class property.

Proposed enhancement
 export class CapabilityError extends Error {
+  public readonly underlyingError?: Error;
+
   constructor(
     message: string,
-    public readonly code: CapabilityErrorCode
+    public readonly code: CapabilityErrorCode,
+    underlyingError?: Error
   ) {
     super(message);
     this.name = 'CapabilityError';
+    this.underlyingError = underlyingError;
+    if (underlyingError) {
+      this.cause = underlyingError;
+    }
   }
 
   static loadFailed(
     resource: string,
     underlyingError?: Error
   ): CapabilityError {
     const message = underlyingError
       ? `Failed to load ${resource}: ${underlyingError.message}`
       : `Failed to load ${resource}: Unknown error`;
-    return new CapabilityError(message, CapabilityErrorCode.LoadFailed);
+    return new CapabilityError(message, CapabilityErrorCode.LoadFailed, underlyingError);
   }

Apply similar changes to operationFailed and compositeComponentFailed.

sdk/runanywhere-react-native/src/Core/Capabilities/LifecycleEvents.ts (2)

57-65: Consider accepting Error objects to preserve metadata.

The error parameter is typed as string, which loses stack traces and structured error information. Consider accepting Error | string to preserve debugging context while maintaining backward compatibility with string error messages.

🔎 Proposed enhancement
 export function createLLMModelLoadFailedEvent(
   modelId: string,
-  error: string
+  error: string | Error
 ): SDKEvent {
   return createSDKEvent('llm_model_load_failed', EventCategory.LLM, {
     model_id: modelId,
-    error,
+    error: error instanceof Error ? error.message : error,
+    error_stack: error instanceof Error ? error.stack : undefined,
   });
 }

Apply similar changes to STT, TTS, VAD, and SpeakerDiarization load failed event creators.


35-39: Consider adding input validation guards.

The event creator functions don't validate inputs. While these are internal SDK functions, adding defensive checks could prevent issues:

  • Empty modelId/voiceId strings
  • Negative durationMs values
🔎 Example validation pattern
 export function createLLMModelLoadCompletedEvent(
   modelId: string,
   durationMs: number
 ): SDKEvent {
+  if (!modelId.trim()) {
+    throw new Error('modelId cannot be empty');
+  }
+  if (durationMs < 0) {
+    throw new Error('durationMs cannot be negative');
+  }
   return createSDKEvent('llm_model_load_completed', EventCategory.LLM, {
     model_id: modelId,
     duration_ms: durationMs.toFixed(1),
   });
 }

Apply similar validation to other event creators as needed.

Also applies to: 44-52

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e31a35e and 108c4a0.

⛔ Files ignored due to path filters (1)
  • sdk/runanywhere-react-native/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (107)
  • sdk/runanywhere-react-native/.yarnrc.yml (1 hunks)
  • sdk/runanywhere-react-native/examples/TTSExample.tsx (0 hunks)
  • sdk/runanywhere-react-native/examples/streaming-llm-example.ts (0 hunks)
  • sdk/runanywhere-react-native/knip.json (1 hunks)
  • sdk/runanywhere-react-native/package.json (5 hunks)
  • sdk/runanywhere-react-native/scripts/check_todos.js (1 hunks)
  • sdk/runanywhere-react-native/scripts/run_analysis.js (1 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/DeviceCapability/Models/DeviceCapabilities.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/DeviceCapability/Services/HardwareCapabilityManager.ts (5 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Memory/Services/AllocationManager.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Memory/Services/CacheEviction.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Memory/Services/MemoryMonitor.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Memory/Services/MemoryService.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Memory/Services/PressureHandler.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/ModelLoading/Models/LoadedModel.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/ModelLoading/Services/ModelLoadingService.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Registry/Services/RegistryService.ts (2 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Models/ExecutionTarget.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Models/RoutingDecision.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Models/RoutingReason.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Services/CostCalculator.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Services/ResourceChecker.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Services/RoutingService.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/StructuredOutput/Services/StructuredOutputHandler.ts (4 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/StructuredOutput/Services/index.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/GenerationOptions.ts (2 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/GenerationResult.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/InferenceRequest.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/PerformanceMetrics.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/index.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Services/GenerationOptionsResolver.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Services/GenerationService.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Services/StreamingService.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Services/ThinkingParser.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Services/TokenCounter.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Capabilities/Analytics/CoreAnalyticsTypes.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Capabilities/Analytics/index.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Capabilities/CapabilityProtocols.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Capabilities/LifecycleEvents.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Capabilities/ManagedLifecycle.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Capabilities/ModelLifecycleManager.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Capabilities/ResourceTypes.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Capabilities/index.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Components/BaseComponent.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Common/RequestPriority.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Common/ResourceAvailability.ts (2 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Common/SDKComponent.ts (2 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Common/TelemetryEventType.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Configuration/LLMConfiguration.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Configuration/STTConfiguration.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Configuration/SpeakerDiarizationConfiguration.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Configuration/TTSConfiguration.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Configuration/VLMConfiguration.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Configuration/WakeWordConfiguration.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Framework/FrameworkModality.ts (2 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Framework/LLMFramework.ts (4 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Model/ModelCategory.ts (4 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Model/ModelFormat.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Model/ModelInfo.ts (3 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Model/ModelInfoMetadata.ts (2 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/Model/index.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/STT/STTTranscriptionResult.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/TTS/TTSResult.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Models/VLM/VLMResult.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/ModuleRegistry.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Component/Component.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/LLM/LLMService.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/LLM/LLMServiceProvider.ts (2 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Lifecycle/ModelLifecycleProtocol.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Memory/MemoryManager.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Memory/MemoryModels.ts (2 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Registry/ModelRegistry.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/VLM/VLMService.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/VLM/VLMServiceProvider.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Voice/STTService.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Voice/STTServiceProvider.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Voice/SpeakerDiarizationService.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Voice/SpeakerDiarizationServiceProvider.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Voice/TTSService.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Voice/WakeWordService.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Core/Protocols/Voice/WakeWordServiceProvider.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Data/Models/Downloading/DownloadProgress.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Data/Models/Downloading/DownloadState.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Data/Models/Downloading/DownloadTask.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Data/Network/APIEndpoint.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Network/Models/AuthModels.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Network/Services/APIClient.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Network/Services/AuthenticationService.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Network/Services/DownloadService.ts (0 hunks)
  • sdk/runanywhere-react-native/src/Data/Network/Services/NetworkService.ts (5 hunks)
  • sdk/runanywhere-react-native/src/Data/Network/index.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Protocols/DataSource.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Protocols/Repository.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Protocols/RepositoryEntity.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Protocols/RepositoryError.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Protocols/index.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Repositories/ModelInfoRepository.ts (2 hunks)
  • sdk/runanywhere-react-native/src/Data/Repositories/index.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Services/ModelInfoService.ts (4 hunks)
  • sdk/runanywhere-react-native/src/Data/Services/index.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/Sync/SyncCoordinator.ts (5 hunks)
  • sdk/runanywhere-react-native/src/Data/Sync/index.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Data/modelCatalog.ts (5 hunks)
  • sdk/runanywhere-react-native/src/Features/LLM/Errors/LLMError.ts (1 hunks)
  • sdk/runanywhere-react-native/src/Features/LLM/LLMCapability.ts (25 hunks)
  • sdk/runanywhere-react-native/src/Features/LLM/LLMConfiguration.ts (3 hunks)
  • sdk/runanywhere-react-native/src/Features/LLM/LLMModels.ts (1 hunks)
⛔ Files not processed due to max files limit (52)
  • sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/Generatable.ts
  • sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/GenerationHints.ts
  • sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/JSONSchemaGenerator.ts
  • sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/README.md
  • sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/StreamAccumulator.ts
  • sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/StreamToken.ts
  • sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/StructuredOutputGenerationService.ts
  • sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/StructuredOutputValidation.ts
  • sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/index.ts
  • sdk/runanywhere-react-native/src/Features/LLM/index.ts
  • sdk/runanywhere-react-native/src/Features/STT/Errors/STTError.ts
  • sdk/runanywhere-react-native/src/Features/STT/STTCapability.ts
  • sdk/runanywhere-react-native/src/Features/STT/STTConfiguration.ts
  • sdk/runanywhere-react-native/src/Features/STT/STTModels.ts
  • sdk/runanywhere-react-native/src/Features/STT/index.ts
  • sdk/runanywhere-react-native/src/Features/SpeakerDiarization/Errors/SpeakerDiarizationError.ts
  • sdk/runanywhere-react-native/src/Features/SpeakerDiarization/Errors/index.ts
  • sdk/runanywhere-react-native/src/Features/SpeakerDiarization/SpeakerDiarizationCapability.ts
  • sdk/runanywhere-react-native/src/Features/SpeakerDiarization/SpeakerDiarizationConfiguration.ts
  • sdk/runanywhere-react-native/src/Features/SpeakerDiarization/SpeakerDiarizationModels.ts
  • sdk/runanywhere-react-native/src/Features/SpeakerDiarization/index.ts
  • sdk/runanywhere-react-native/src/Features/TTS/Errors/TTSError.ts
  • sdk/runanywhere-react-native/src/Features/TTS/TTSCapability.ts
  • sdk/runanywhere-react-native/src/Features/TTS/TTSConfiguration.ts
  • sdk/runanywhere-react-native/src/Features/TTS/TTSModels.ts
  • sdk/runanywhere-react-native/src/Features/TTS/index.ts
  • sdk/runanywhere-react-native/src/Features/VAD/Errors/VADError.ts
  • sdk/runanywhere-react-native/src/Features/VAD/VADCapability.ts
  • sdk/runanywhere-react-native/src/Features/VAD/VADConfiguration.ts
  • sdk/runanywhere-react-native/src/Features/VAD/index.ts
  • sdk/runanywhere-react-native/src/Features/VoiceAgent/Models/AudioPipelineState.ts
  • sdk/runanywhere-react-native/src/Features/VoiceAgent/Models/index.ts
  • sdk/runanywhere-react-native/src/Features/VoiceAgent/VoiceAgentCapability.ts
  • sdk/runanywhere-react-native/src/Features/VoiceAgent/VoiceAgentConfiguration.ts
  • sdk/runanywhere-react-native/src/Features/VoiceAgent/VoiceAgentModels.ts
  • sdk/runanywhere-react-native/src/Features/VoiceAgent/index.ts
  • sdk/runanywhere-react-native/src/Features/VoiceSession/VoiceSessionConfig.ts
  • sdk/runanywhere-react-native/src/Features/VoiceSession/VoiceSessionError.ts
  • sdk/runanywhere-react-native/src/Features/VoiceSession/VoiceSessionEvent.ts
  • sdk/runanywhere-react-native/src/Features/VoiceSession/VoiceSessionHandle.ts
  • sdk/runanywhere-react-native/src/Features/VoiceSession/index.ts
  • sdk/runanywhere-react-native/src/Features/index.ts
  • sdk/runanywhere-react-native/src/Foundation/Analytics/AnalyticsQueueManager.ts
  • sdk/runanywhere-react-native/src/Foundation/Configuration/ConfigurationService.ts
  • sdk/runanywhere-react-native/src/Foundation/Constants/SDKConstants.ts
  • sdk/runanywhere-react-native/src/Foundation/DependencyInjection/AdapterRegistry.ts
  • sdk/runanywhere-react-native/src/Foundation/DependencyInjection/ServiceContainer.ts
  • sdk/runanywhere-react-native/src/Foundation/DependencyInjection/ServiceRegistry.ts
  • sdk/runanywhere-react-native/src/Foundation/DependencyInjection/index.ts
  • sdk/runanywhere-react-native/src/Foundation/DeviceIdentity/DeviceIdentityService.ts
  • sdk/runanywhere-react-native/src/Foundation/ErrorTypes/ErrorCategory.ts
  • sdk/runanywhere-react-native/src/Foundation/ErrorTypes/ErrorCodes.ts
💤 Files with no reviewable changes (44)
  • sdk/runanywhere-react-native/src/Data/Models/Downloading/DownloadProgress.ts
  • sdk/runanywhere-react-native/src/Core/Models/VLM/VLMResult.ts
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Services/TokenCounter.ts
  • sdk/runanywhere-react-native/src/Core/Models/Configuration/STTConfiguration.ts
  • sdk/runanywhere-react-native/src/Capabilities/ModelLoading/Models/LoadedModel.ts
  • sdk/runanywhere-react-native/src/Core/Protocols/VLM/VLMService.ts
  • sdk/runanywhere-react-native/src/Core/Protocols/Voice/WakeWordServiceProvider.ts
  • sdk/runanywhere-react-native/src/Capabilities/Memory/Services/AllocationManager.ts
  • sdk/runanywhere-react-native/src/Capabilities/StructuredOutput/Services/index.ts
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Models/ExecutionTarget.ts
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Services/CostCalculator.ts
  • sdk/runanywhere-react-native/src/Capabilities/Memory/Services/MemoryService.ts
  • sdk/runanywhere-react-native/src/Data/Network/Services/DownloadService.ts
  • sdk/runanywhere-react-native/src/Core/Models/Common/TelemetryEventType.ts
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Services/StreamingService.ts
  • sdk/runanywhere-react-native/src/Capabilities/ModelLoading/Services/ModelLoadingService.ts
  • sdk/runanywhere-react-native/src/Capabilities/Memory/Services/PressureHandler.ts
  • sdk/runanywhere-react-native/src/Data/Models/Downloading/DownloadTask.ts
  • sdk/runanywhere-react-native/src/Capabilities/Memory/Services/CacheEviction.ts
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Services/GenerationService.ts
  • sdk/runanywhere-react-native/src/Data/Models/Downloading/DownloadState.ts
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Services/RoutingService.ts
  • sdk/runanywhere-react-native/src/Core/Models/Common/RequestPriority.ts
  • sdk/runanywhere-react-native/src/Core/Protocols/Voice/WakeWordService.ts
  • sdk/runanywhere-react-native/src/Core/Protocols/VLM/VLMServiceProvider.ts
  • sdk/runanywhere-react-native/src/Core/Models/Configuration/WakeWordConfiguration.ts
  • sdk/runanywhere-react-native/src/Core/Protocols/Component/Component.ts
  • sdk/runanywhere-react-native/src/Capabilities/Memory/Services/MemoryMonitor.ts
  • sdk/runanywhere-react-native/src/Core/Protocols/Lifecycle/ModelLifecycleProtocol.ts
  • sdk/runanywhere-react-native/src/Core/Models/Configuration/SpeakerDiarizationConfiguration.ts
  • sdk/runanywhere-react-native/src/Core/ModuleRegistry.ts
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Models/RoutingDecision.ts
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Models/RoutingReason.ts
  • sdk/runanywhere-react-native/examples/TTSExample.tsx
  • sdk/runanywhere-react-native/examples/streaming-llm-example.ts
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/InferenceRequest.ts
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/index.ts
  • sdk/runanywhere-react-native/src/Core/Models/Configuration/VLMConfiguration.ts
  • sdk/runanywhere-react-native/src/Capabilities/Routing/Services/ResourceChecker.ts
  • sdk/runanywhere-react-native/src/Core/Models/Model/index.ts
  • sdk/runanywhere-react-native/src/Core/Models/Configuration/LLMConfiguration.ts
  • sdk/runanywhere-react-native/src/Core/Protocols/Memory/MemoryManager.ts
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Services/GenerationOptionsResolver.ts
  • sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Services/ThinkingParser.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/components/**/*.kt : Implement proper component lifecycle management with initialization, state tracking, and cleanup in BaseComponent.

Applied to files:

  • sdk/runanywhere-react-native/src/Core/Components/BaseComponent.ts
  • sdk/runanywhere-react-native/src/Core/Models/Common/SDKComponent.ts
🧬 Code graph analysis (25)
sdk/runanywhere-react-native/src/Core/Models/Framework/FrameworkModality.ts (1)
sdk/runanywhere-react-native/src/types/index.ts (1)
  • FrameworkModality (12-12)
sdk/runanywhere-react-native/src/Core/Protocols/LLM/LLMService.ts (2)
sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/GenerationOptions.ts (1)
  • GenerationOptions (24-54)
sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/GenerationResult.ts (1)
  • GenerationResult (18-60)
sdk/runanywhere-react-native/src/Core/Protocols/Memory/MemoryModels.ts (1)
sdk/runanywhere-react-native/src/Core/Protocols/LLM/LLMService.ts (1)
  • LLMService (13-50)
sdk/runanywhere-react-native/src/Capabilities/DeviceCapability/Models/DeviceCapabilities.ts (2)
sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/GenerationOptions.ts (1)
  • HardwareAcceleration (17-17)
sdk/runanywhere-react-native/src/types/index.ts (1)
  • HardwareAcceleration (13-13)
sdk/runanywhere-react-native/src/Core/Models/Model/ModelInfo.ts (1)
sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/ThinkingTagPattern.ts (1)
  • ThinkingTagPatternImpl (20-44)
sdk/runanywhere-react-native/src/Features/LLM/Errors/LLMError.ts (2)
sdk/runanywhere-react-native/src/Features/LLM/index.ts (1)
  • LLMError (61-61)
sdk/runanywhere-react-native/src/index.ts (3)
  • LLMError (162-162)
  • SDKError (66-66)
  • ErrorCode (48-48)
sdk/runanywhere-react-native/src/Data/Protocols/Repository.ts (2)
sdk/runanywhere-react-native/src/Data/Protocols/DataSource.ts (1)
  • RemoteDataSource (26-57)
sdk/runanywhere-react-native/src/Data/Protocols/RepositoryEntity.ts (1)
  • RepositoryEntity (5-17)
sdk/runanywhere-react-native/src/Core/Protocols/Voice/SpeakerDiarizationService.ts (1)
sdk/runanywhere-react-native/src/Core/Models/SpeakerDiarization/SpeakerDiarizationResult.ts (1)
  • SpeakerDiarizationResult (9-12)
sdk/runanywhere-react-native/src/Data/Protocols/DataSource.ts (3)
sdk/runanywhere-react-native/src/index.ts (7)
  • DataSource (218-218)
  • RemoteDataSource (219-219)
  • LocalDataSource (220-220)
  • DataSourceStorageInfo (221-221)
  • DataSourceError (222-222)
  • DataSourceErrorCode (223-223)
  • RemoteOperationHelper (224-224)
sdk/runanywhere-react-native/src/Data/Protocols/index.ts (7)
  • DataSource (9-9)
  • RemoteDataSource (10-10)
  • LocalDataSource (11-11)
  • DataSourceStorageInfo (12-12)
  • DataSourceError (13-13)
  • DataSourceErrorCode (14-14)
  • RemoteOperationHelper (15-15)
sdk/runanywhere-react-native/src/Infrastructure/Download/Errors/DownloadError.ts (1)
  • timeout (38-40)
sdk/runanywhere-react-native/src/Core/Models/Model/ModelFormat.ts (1)
sdk/runanywhere-react-native/src/index.ts (1)
  • ModelFormat (26-26)
sdk/runanywhere-react-native/src/Core/Capabilities/ResourceTypes.ts (2)
sdk/runanywhere-react-native/src/Core/Capabilities/index.ts (2)
  • CapabilityResourceType (41-41)
  • getResourceTypeDisplayName (42-42)
sdk/runanywhere-react-native/src/index.ts (1)
  • CapabilityResourceType (253-253)
sdk/runanywhere-react-native/src/Core/Capabilities/ModelLifecycleManager.ts (1)
sdk/runanywhere-react-native/src/Core/Capabilities/CapabilityProtocols.ts (5)
  • CapabilityLoadingState (16-20)
  • loadedState (39-41)
  • loadingState (32-34)
  • idleState (25-27)
  • CapabilityError (265-327)
sdk/runanywhere-react-native/src/Core/Protocols/Voice/TTSService.ts (3)
sdk/runanywhere-react-native/src/index.ts (1)
  • TTSConfiguration (148-148)
sdk/runanywhere-react-native/src/types/models.ts (2)
  • TTSConfiguration (339-351)
  • TTSResult (356-368)
sdk/runanywhere-react-native/src/Core/Models/Configuration/TTSConfiguration.ts (1)
  • TTSConfiguration (11-23)
sdk/runanywhere-react-native/src/Core/Capabilities/ManagedLifecycle.ts (7)
sdk/runanywhere-react-native/src/Core/Capabilities/ModelLifecycleManager.ts (3)
  • ModelLifecycleManager (89-269)
  • LoadResourceFn (30-33)
  • UnloadResourceFn (39-39)
sdk/runanywhere-react-native/src/Core/Capabilities/LifecycleEvents.ts (20)
  • createLLMModelLoadStartedEvent (35-39)
  • createLLMModelLoadCompletedEvent (44-52)
  • createLLMModelLoadFailedEvent (57-65)
  • createLLMModelUnloadedEvent (70-74)
  • createSTTModelLoadStartedEvent (92-96)
  • createSTTModelLoadCompletedEvent (101-109)
  • createSTTModelLoadFailedEvent (114-122)
  • createSTTModelUnloadedEvent (127-131)
  • createTTSModelLoadStartedEvent (149-153)
  • createTTSModelLoadCompletedEvent (158-166)
  • createTTSModelLoadFailedEvent (171-179)
  • createTTSModelUnloadedEvent (184-188)
  • createVADModelLoadStartedEvent (206-210)
  • createVADModelLoadCompletedEvent (215-223)
  • createVADModelLoadFailedEvent (228-236)
  • createVADModelUnloadedEvent (241-245)
  • createSpeakerDiarizationModelLoadStartedEvent (263-273)
  • createSpeakerDiarizationModelLoadCompletedEvent (278-290)
  • createSpeakerDiarizationModelLoadFailedEvent (295-307)
  • createSpeakerDiarizationModelUnloadedEvent (312-322)
sdk/runanywhere-react-native/src/Core/Capabilities/CapabilityProtocols.ts (2)
  • CapabilityLoadingState (16-20)
  • ComponentConfiguration (124-130)
sdk/runanywhere-react-native/src/Infrastructure/Events/CommonEvents.ts (3)
  • createErrorEvent (445-460)
  • createModelDownloadStartedEvent (113-123)
  • createModelDownloadCompletedEvent (152-168)
sdk/runanywhere-react-native/src/Infrastructure/Events/EventPublisher.ts (1)
  • EventPublisher (234-237)
sdk/runanywhere-react-native/src/Core/Capabilities/Analytics/CoreAnalyticsTypes.ts (1)
  • ModelLifecycleMetrics (59-70)
sdk/runanywhere-react-native/src/Infrastructure/Events/SDKEvent.ts (1)
  • SDKEvent (92-133)
sdk/runanywhere-react-native/src/Capabilities/DeviceCapability/Services/HardwareCapabilityManager.ts (5)
sdk/runanywhere-react-native/src/Foundation/Logging/Logger/SDKLogger.ts (2)
  • SDKLogger (15-72)
  • error (51-53)
sdk/runanywhere-react-native/src/Capabilities/DeviceCapability/Models/DeviceCapabilities.ts (2)
  • DeviceCapabilities (54-67)
  • DeviceCapabilitiesImpl (72-132)
sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/GenerationOptions.ts (1)
  • HardwareAcceleration (17-17)
sdk/runanywhere-react-native/src/types/models.ts (1)
  • ModelInfo (50-116)
sdk/runanywhere-react-native/src/Core/Models/Common/ResourceAvailability.ts (1)
  • ResourceAvailability (24-59)
sdk/runanywhere-react-native/src/Capabilities/TextGeneration/Models/GenerationOptions.ts (2)
sdk/runanywhere-react-native/src/Capabilities/StructuredOutput/Services/StructuredOutputHandler.ts (1)
  • StructuredOutputConfig (25-30)
sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/Generatable.ts (1)
  • StructuredOutputConfig (32-42)
sdk/runanywhere-react-native/src/Data/Network/APIEndpoint.ts (2)
sdk/runanywhere-react-native/src/Foundation/Constants/SDKConstants.ts (1)
  • platform (37-39)
sdk/runanywhere-react-native/src/types/index.ts (1)
  • SDKEnvironment (22-22)
sdk/runanywhere-react-native/src/Data/Network/Services/AuthenticationService.ts (4)
sdk/runanywhere-react-native/src/Data/Network/index.ts (9)
  • AuthenticationService (44-44)
  • AuthenticationProvider (41-41)
  • APIClient (37-37)
  • AuthenticationResponse (49-49)
  • AuthenticationRequest (48-48)
  • toInternalAuthResponse (55-55)
  • HealthCheckResponse (54-54)
  • RefreshTokenRequest (50-50)
  • RefreshTokenResponse (51-51)
sdk/runanywhere-react-native/src/Infrastructure/Device/Services/DeviceRegistrationService.ts (1)
  • deviceId (128-130)
sdk/runanywhere-react-native/src/Foundation/Security/SecureStorageService.ts (1)
  • SecureStorageService (423-423)
sdk/runanywhere-react-native/src/Public/Errors/SDKError.ts (2)
  • SDKError (15-15)
  • SDKErrorCode (13-13)
sdk/runanywhere-react-native/src/Core/Models/Common/SDKComponent.ts (1)
sdk/runanywhere-react-native/src/types/index.ts (1)
  • SDKComponent (21-21)
sdk/runanywhere-react-native/src/Core/Models/Model/ModelCategory.ts (2)
sdk/runanywhere-react-native/src/index.ts (2)
  • ModelCategory (25-25)
  • LLMFramework (24-24)
sdk/runanywhere-react-native/src/types/index.ts (3)
  • ModelCategory (16-16)
  • FrameworkModality (12-12)
  • LLMFramework (14-14)
sdk/runanywhere-react-native/src/Data/Network/Services/NetworkService.ts (1)
sdk/runanywhere-react-native/src/index.ts (1)
  • APIEndpointDefinition (193-193)
sdk/runanywhere-react-native/src/Capabilities/StructuredOutput/Services/StructuredOutputHandler.ts (3)
sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/Generatable.ts (1)
  • StructuredOutputConfig (32-42)
sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/StructuredOutputGenerationService.ts (1)
  • StructuredOutputError (57-94)
sdk/runanywhere-react-native/src/Features/LLM/StructuredOutput/StructuredOutputValidation.ts (1)
  • StructuredOutputError (33-69)
sdk/runanywhere-react-native/src/Features/LLM/LLMConfiguration.ts (2)
sdk/runanywhere-react-native/src/Core/Capabilities/CapabilityProtocols.ts (1)
  • ComponentConfiguration (124-130)
sdk/runanywhere-react-native/src/Core/Models/Common/ComponentInitParameters.ts (1)
  • ComponentInitParameters (14-30)
sdk/runanywhere-react-native/src/Core/Capabilities/CapabilityProtocols.ts (3)
sdk/runanywhere-react-native/src/Core/Capabilities/index.ts (11)
  • CapabilityLoadingState (12-12)
  • idleState (13-13)
  • loadingState (14-14)
  • loadedState (15-15)
  • failedState (16-16)
  • isIdle (17-17)
  • isLoading (18-18)
  • isLoaded (19-19)
  • isFailed (20-20)
  • getResourceId (21-21)
  • Capability (28-28)
sdk/runanywhere-react-native/src/index.ts (6)
  • CapabilityLoadingState (247-247)
  • isIdle (248-248)
  • isLoading (249-249)
  • isLoaded (250-250)
  • isFailed (251-251)
  • Capability (241-241)
sdk/runanywhere-react-native/src/Core/Capabilities/ModelLifecycleManager.ts (2)
  • state (137-145)
  • isLoaded (116-118)
sdk/runanywhere-react-native/src/Data/Sync/SyncCoordinator.ts (4)
sdk/runanywhere-react-native/src/index.ts (2)
  • RepositoryEntity (215-215)
  • SyncableRepository (212-212)
sdk/runanywhere-react-native/src/Data/Protocols/RepositoryEntity.ts (1)
  • RepositoryEntity (5-17)
sdk/runanywhere-react-native/src/Data/Protocols/index.ts (2)
  • RepositoryEntity (1-1)
  • SyncableRepository (5-5)
sdk/runanywhere-react-native/src/Data/Protocols/Repository.ts (1)
  • SyncableRepository (50-62)

Comment on lines 87 to 98
"@typescript-eslint/eslint-plugin": "^8.50.0",
"@typescript-eslint/parser": "^8.50.0",
"commitlint": "^17.0.2",
"del-cli": "^5.1.0",
"eslint": "^8.51.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-jest": "^29.5.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-unused-imports": "^4.3.0",
"glob": "^13.0.0",
"jest": "^29.7.0",
"knip": "^5.76.0",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Update ESLint minimum version to 8.57.0.

The version range of ESLint currently supported by @typescript-eslint is ^8.57.0 || ^9.0.0. The current eslint@^8.51.0 specification does not meet this requirement. Upgrade to eslint@^8.57.0 to ensure compatibility with @typescript-eslint/eslint-plugin and @typescript-eslint/parser at version 8.50.0. TypeScript 5.2.2 is within the supported range of >=4.8.4 <6.0.0, so no changes are needed for the TypeScript dependency.

🤖 Prompt for AI Agents
In sdk/runanywhere-react-native/package.json around lines 87 to 98, eslint is
pinned to ^8.51.0 which is incompatible with @typescript-eslint@8.50.0; update
the eslint dependency to ^8.57.0 to satisfy @typescript-eslint's supported range
and ensure compatibility (leave other related linting/dependency versions
unchanged).

Comment on lines +61 to +84
results.eslint = runCommand(
'yarn eslint "src/**/*.ts" --format json 2>&1 || true',
path.join(ITERATION_DIR, 'eslint.json')
);

// 3. Knip (unused code detection)
console.log('\n[3/4] Knip (Unused Code Detection)');
results.knip = runCommand(
'yarn knip --reporter json 2>&1 || true',
path.join(ITERATION_DIR, 'knip.json')
);

// Also get human-readable knip output
runCommand(
'yarn knip 2>&1 || true',
path.join(ITERATION_DIR, 'knip.txt')
);

// 4. TODO Check
console.log('\n[4/4] TODO Comment Check');
results.todos = runCommand(
'node scripts/check_todos.js 2>&1 || true',
path.join(ITERATION_DIR, 'todos.txt')
);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

|| true masks tool failures, causing incorrect success status.

Commands like yarn eslint ... || true always exit with code 0, so execSync never throws. This means results.eslint.success (and others) will always be true, even when the tools report issues. The summary will incorrectly show "PASS" for all tools.

🔎 Proposed fix

Remove || true from commands and let the catch block handle non-zero exits:

   // 2. ESLint
   console.log('\n[2/4] ESLint');
   results.eslint = runCommand(
-    'yarn eslint "src/**/*.ts" --format json 2>&1 || true',
+    'yarn eslint "src/**/*.ts" --format json 2>&1',
     path.join(ITERATION_DIR, 'eslint.json')
   );

   // 3. Knip (unused code detection)
   console.log('\n[3/4] Knip (Unused Code Detection)');
   results.knip = runCommand(
-    'yarn knip --reporter json 2>&1 || true',
+    'yarn knip --reporter json 2>&1',
     path.join(ITERATION_DIR, 'knip.json')
   );

   // Also get human-readable knip output
   runCommand(
-    'yarn knip 2>&1 || true',
+    'yarn knip 2>&1',
     path.join(ITERATION_DIR, 'knip.txt')
   );

   // 4. TODO Check
   console.log('\n[4/4] TODO Comment Check');
   results.todos = runCommand(
-    'node scripts/check_todos.js 2>&1 || true',
+    'node scripts/check_todos.js 2>&1',
     path.join(ITERATION_DIR, 'todos.txt')
   );
🤖 Prompt for AI Agents
In sdk/runanywhere-react-native/scripts/run_analysis.js around lines 61 to 84
the shell fragments append "|| true" to eslint, knip and todo commands which
masks non-zero exits so execSync never throws and results.*.success is always
true; remove the "|| true" from those command strings (keep any necessary 2>&1
redirection) so that failing tools produce non-zero exits, allowing the existing
try/catch and result.success logic to correctly detect failures and record
output files as before.

Comment on lines 186 to 190
// Get CPU cores (sync method)
const processorCount =
DeviceInfo.getSupportedAbisSync().length > 0
? Math.max(2, navigator?.hardwareConcurrency ?? 4)
: 4;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

navigator.hardwareConcurrency is not available in React Native.

navigator.hardwareConcurrency is a Web API that doesn't exist in React Native's JavaScript runtime. This will always be undefined, causing the fallback to 4. Additionally, checking getSupportedAbisSync().length isn't logically related to determining CPU core count.

Consider using a platform-specific approach or a reasonable default based on device model:

🔎 Proposed fix
       // Get CPU cores (sync method)
-      const processorCount =
-        DeviceInfo.getSupportedAbisSync().length > 0
-          ? Math.max(2, navigator?.hardwareConcurrency ?? 4)
-          : 4;
+      // React Native doesn't expose CPU core count directly
+      // Use reasonable defaults based on platform and device era
+      const processorCount = Platform.OS === 'ios' 
+        ? 6  // Modern iPhones have 6 cores (2 performance + 4 efficiency)
+        : 8; // Most modern Android devices have 8 cores

Alternatively, consider removing this field or documenting it always returns an estimated value.

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 363 to 385
if (Platform.OS === 'ios') {
// A-series chips
if (device.includes('iphone16') || device.includes('ipad15')) {
return ProcessorType.A18Pro;
}
if (device.includes('iphone15') || device.includes('ipad14')) {
return ProcessorType.A17Pro;
}
if (device.includes('iphone14') || device.includes('ipad13')) {
return ProcessorType.A16Bionic;
}
if (device.includes('iphone13') || device.includes('ipad12')) {
return ProcessorType.A15Bionic;
}
if (device.includes('iphone12') || device.includes('ipad11')) {
return ProcessorType.A14Bionic;
}

// M-series (iPad Pro, Mac)
if (device.includes('mac') || device.includes('ipad14')) {
return ProcessorType.M2;
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Incorrect Apple device identifier to processor mapping.

Apple's device identifiers don't match marketing names. For example:

  • iPhone16,x = iPhone 15 series (A16/A17 Pro)
  • iPhone15,x = iPhone 14 series (A15/A16)
  • iPhone14,x = iPhone 13 series (A15)

The current logic will misidentify processors. Also, line 382 checks ipad14 for M2 after line 368 already matched it for A17Pro.

🔎 Proposed fix with correct mappings
   private detectProcessorType(
     deviceId: string,
     supportedAbis: string[]
   ): ProcessorType {
     const device = deviceId.toLowerCase();

     if (Platform.OS === 'ios') {
-      // A-series chips
-      if (device.includes('iphone16') || device.includes('ipad15')) {
-        return ProcessorType.A18Pro;
-      }
-      if (device.includes('iphone15') || device.includes('ipad14')) {
-        return ProcessorType.A17Pro;
-      }
-      if (device.includes('iphone14') || device.includes('ipad13')) {
-        return ProcessorType.A16Bionic;
-      }
-      if (device.includes('iphone13') || device.includes('ipad12')) {
-        return ProcessorType.A15Bionic;
-      }
-      if (device.includes('iphone12') || device.includes('ipad11')) {
-        return ProcessorType.A14Bionic;
-      }
-
-      // M-series (iPad Pro, Mac)
-      if (device.includes('mac') || device.includes('ipad14')) {
-        return ProcessorType.M2;
-      }
+      // Extract numeric identifier (e.g., "iphone17,1" -> 17)
+      const iPhoneMatch = device.match(/iphone(\d+)/);
+      if (iPhoneMatch) {
+        const generation = parseInt(iPhoneMatch[1], 10);
+        // iPhone17,x = iPhone 16 (A18/A18 Pro)
+        if (generation >= 17) return ProcessorType.A18Pro;
+        // iPhone16,x = iPhone 15 (A16/A17 Pro)
+        if (generation === 16) return ProcessorType.A17Pro;
+        // iPhone15,x = iPhone 14 (A15/A16)
+        if (generation === 15) return ProcessorType.A16Bionic;
+        // iPhone14,x = iPhone 13 (A15)
+        if (generation === 14) return ProcessorType.A15Bionic;
+        // iPhone13,x = iPhone 12 (A14)
+        if (generation === 13) return ProcessorType.A14Bionic;
+      }
+
+      // M-series detection for iPad/Mac
+      if (device.includes('mac')) {
+        return ProcessorType.M2;
+      }
     }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 21 to 23
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- ModelDiscovery type not yet defined
private modelDiscovery: any;
private readonly logger = new SDKLogger('RegistryService');
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find and examine the RegistryService.ts file
fd -t f 'RegistryService.ts' --exec cat -n {} \;

Repository: RunanywhereAI/runanywhere-sdks

Length of output: 6337


🏁 Script executed:

#!/bin/bash
# Check the ServiceContainer implementation
fd -t f 'ServiceContainer.ts' --exec cat -n {} \;

Repository: RunanywhereAI/runanywhere-sdks

Length of output: 12009


modelDiscovery field is never initialized and typed as any.

The field is declared but never assigned in the constructor or through any initialization mechanism, so this.modelDiscovery?.discoverLocalModels() on line 38 will always return undefined (falling back to []). Model discovery functionality cannot work unless this field is properly initialized via dependency injection or a setter method.

Additionally, the _apiKey parameter in the initialize method is unused, and registerModelPersistently has its persistence logic commented out, making it non-functional.

Comment on lines 53 to 54
/** Timestamp of when the result was created */
timestamp: Date;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Date type doesn't survive React Native bridge serialization.

The timestamp field is typed as Date, but data crossing the RN bridge (via JSON serialization) will arrive as a string (ISO format) or number, not a Date instance. Calling result.timestamp.getTime() or similar methods will fail at runtime.

Consider using number (epoch milliseconds) or string (ISO format) to match the actual serialized representation, or add a note that consumers must manually convert.

🔎 Suggested fix using number (epoch milliseconds)
-  /** Timestamp of when the result was created */
-  timestamp: Date;
+  /** Timestamp of when the result was created (epoch milliseconds) */
+  timestamp: number;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/** Timestamp of when the result was created */
timestamp: Date;
/** Timestamp of when the result was created (epoch milliseconds) */
timestamp: number;
🤖 Prompt for AI Agents
sdk/runanywhere-react-native/src/Core/Models/TTS/TTSResult.ts around lines 53 to
54, the timestamp is typed as Date which is not preserved across the React
Native bridge (JSON serialization yields a string or number), so update the type
to a serialized form (prefer number representing epoch milliseconds) and adjust
the JSDoc to state that timestamp is epoch ms; ensure any code constructing
TTSResult sets timestamp to Date.now() (or converts Date to .getTime()) and any
consumers convert the number back to a Date if needed.

Comment on lines 21 to 25
const SDK_CONSTANTS = {
clientName: 'RunAnywhereSDK-RN',
version: '0.1.0',
platform: 'react-native',
} as const;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for version string 0.1.0 and SDKConstants usage across the codebase
echo "=== Searching for version 0.1.0 ==="
rg "0\.1\.0" --type=ts --type=js -n

echo ""
echo "=== Searching for SDKConstants references ==="
rg "SDKConstants" --type=ts --type=js -n -B2 -A2

echo ""
echo "=== Checking if constants are imported elsewhere ==="
rg "version" --type=ts --type=json | grep -i "constant\|const" | head -20

Repository: RunanywhereAI/runanywhere-sdks

Length of output: 5689


Import version from centralized SDKConstants instead of defining a local constant.

APIClient.ts defines its own local SDK_CONSTANTS with version '0.1.0' on line 23, but a centralized SDKConstants module already exists at sdk/runanywhere-react-native/src/Foundation/Constants/SDKConstants.ts with version '0.15.8'. This creates version inconsistency across the codebase. Import SDKConstants from '../Foundation/Constants/SDKConstants' and use SDKConstants.version instead of maintaining a local duplicate.

🤖 Prompt for AI Agents
In sdk/runanywhere-react-native/src/Data/Network/Services/APIClient.ts around
lines 21 to 25, the file defines a local SDK_CONSTANTS object with a hardcoded
version ('0.1.0'); replace this local constant by importing the centralized
SDKConstants from ../Foundation/Constants/SDKConstants and use
SDKConstants.version (and optionally SDKConstants.clientName/platform if
available) so the module relies on the single source of truth for the SDK
version and avoids duplication.

Comment on lines 31 to 60
post<T, R>(
endpoint: APIEndpoint | APIEndpointDefinition,
payload: T,
requiresAuth?: boolean
): Promise<R>;

/**
* Perform a GET request
* Perform a typed GET request
*/
get<R>(endpoint: APIEndpoint, requiresAuth?: boolean): Promise<R>;
get<R>(
endpoint: APIEndpoint | APIEndpointDefinition,
requiresAuth?: boolean
): Promise<R>;

/**
* Perform a raw POST request (returns Data)
* Perform a raw POST request (returns ArrayBuffer/Data)
*/
postRaw(endpoint: APIEndpoint, payload: ArrayBuffer, requiresAuth?: boolean): Promise<ArrayBuffer>;
postRaw(
endpoint: APIEndpoint | APIEndpointDefinition,
payload: ArrayBuffer,
requiresAuth?: boolean
): Promise<ArrayBuffer>;

/**
* Perform a raw GET request (returns Data)
* Perform a raw GET request (returns ArrayBuffer/Data)
*/
getRaw(endpoint: APIEndpoint, requiresAuth?: boolean): Promise<ArrayBuffer>;
getRaw(
endpoint: APIEndpoint | APIEndpointDefinition,
requiresAuth?: boolean
): Promise<ArrayBuffer>;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find and examine the NetworkService file
fd -t f NetworkService.ts --exec cat {} \;

Repository: RunanywhereAI/runanywhere-sdks

Length of output: 3854


🏁 Script executed:

#!/bin/bash
# Find APIEndpointDefinition definition
fd -t f APIEndpoint.ts --exec cat {} \;

Repository: RunanywhereAI/runanywhere-sdks

Length of output: 5335


🏁 Script executed:

#!/bin/bash
# Verify the type compatibility by checking if the interfaces are truly identical
cat <<'EOF' > /tmp/type_check.ts
import type { APIEndpoint } from './NetworkService';
import type { APIEndpointDefinition } from './APIEndpoint';

// Check structural compatibility
const apiEndpoint: APIEndpoint = { path: '/test', method: 'GET' };
const apiEndpointDef: APIEndpointDefinition = { path: '/test', method: 'GET' };

// Can we assign one to the other?
const test1: APIEndpoint = apiEndpointDef; // Does this work?
const test2: APIEndpointDefinition = apiEndpoint; // Does this work?
EOF

# Search for any actual usage of NetworkServiceImpl methods to see if union type is ever used
rg "new NetworkServiceImpl|NetworkServiceImpl" --type=ts -A5 -B5

Repository: RunanywhereAI/runanywhere-sdks

Length of output: 1906


🏁 Script executed:

#!/bin/bash
# Check if TypeScript compilation would catch this error
# Look for tsconfig and check strict mode settings
fd -t f tsconfig.json --exec cat {} \;

Repository: RunanywhereAI/runanywhere-sdks

Length of output: 1887


Update NetworkServiceImpl to match interface parameter types

The NetworkService interface declares methods accepting APIEndpoint | APIEndpointDefinition, but NetworkServiceImpl implementations (lines 73, 93, 103, 133) only accept APIEndpoint. This violates the Liskov Substitution Principle and creates a type contract mismatch. While APIEndpoint and APIEndpointDefinition are structurally identical, the interface declares a broader contract that the implementation must honor.

Update all four methods in NetworkServiceImpl to accept the union type:

  • post<T, R>(endpoint: APIEndpoint | APIEndpointDefinition, ...)
  • get<R>(endpoint: APIEndpoint | APIEndpointDefinition, ...)
  • postRaw(endpoint: APIEndpoint | APIEndpointDefinition, ...)
  • getRaw(endpoint: APIEndpoint | APIEndpointDefinition, ...)
🤖 Prompt for AI Agents
In sdk/runanywhere-react-native/src/Data/Network/Services/NetworkService.ts
around lines 31-60 (and update implementations at ~73, 93, 103, 133), the
interface methods accept APIEndpoint | APIEndpointDefinition but
NetworkServiceImpl methods currently only accept APIEndpoint; change the four
implementation method signatures (post, get, postRaw, getRaw) to accept the
union type APIEndpoint | APIEndpointDefinition so the class conforms to the
interface contract; ensure any internal usage still treats the endpoint as the
same structural type (no runtime changes required) and update any related type
annotations or imports if necessary.

Comment on lines 21 to 22
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- SyncCoordinator type not yet defined
private syncCoordinator: any | null;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Replace any type with proper SyncCoordinator type.

The use of any for syncCoordinator removes type safety and could lead to runtime errors. While the comment indicates the type is "not yet defined," the AI summary mentions SyncCoordinator.ts exists with a sync<T> method.

🔎 Suggested approach

Import the SyncCoordinator type and update the typing:

+import type { SyncCoordinator } from '../Sync/SyncCoordinator';
+
 export class ModelInfoService {
   private logger: SDKLogger;
   private modelInfoRepository: ModelInfoRepository;
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- SyncCoordinator type not yet defined
-  private syncCoordinator: any | null;
+  private syncCoordinator: SyncCoordinator | null;

And in the constructor:

   constructor(
     modelInfoRepository: ModelInfoRepository,
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any -- SyncCoordinator type not yet defined
-    syncCoordinator?: any | null
+    syncCoordinator?: SyncCoordinator | null
   ) {

Also applies to: 33-34

🤖 Prompt for AI Agents
In sdk/runanywhere-react-native/src/Data/Services/ModelInfoService.ts around
lines 21-22 and 33-34, the syncCoordinator field and related constructor/use
sites are typed as any; replace those any types with the actual SyncCoordinator
interface to restore type safety: import the SyncCoordinator type from its
module (where SyncCoordinator.ts lives), change the private syncCoordinator
declaration to SyncCoordinator | null, update the constructor parameter and any
assignments to use SyncCoordinator (or nullable) and adjust calls to sync<T> to
match the generic signature; ensure imports and nullable checks (if any) compile
without changing runtime behavior.

Comment on lines 30 to 37
static noProviderFound(modelId?: string): LLMError {
const message = modelId
? `No LLM provider found for model: ${modelId}`
: 'No LLM provider registered. Register one with ModuleRegistry.shared.registerLLM(provider).';
return new LLMError(ErrorCode.ModelNotFound, message, {
details: { modelId },
});
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Search for ModuleRegistry class definition and usage in the codebase
rg -nP 'class ModuleRegistry|ModuleRegistry\s*\{' -A5 -B2

# Search for ServiceRegistry definition and LLM registration
rg -nP 'ServiceRegistry|registerLLM' -A3 -B3

# Check if ModuleRegistry exists in the codebase at all
fd -t f '\.ts$|\.tsx$|\.js$' | xargs grep -l 'ModuleRegistry' | head -20

Repository: RunanywhereAI/runanywhere-sdks

Length of output: 50388


🏁 Script executed:

# Get the exact method signature from ServiceRegistry
sed -n '590,610p' sdk/runanywhere-react-native/src/Foundation/DependencyInjection/ServiceRegistry.ts

Repository: RunanywhereAI/runanywhere-sdks

Length of output: 754


Update the LLM provider registration API reference in the error message.

Line 33 references ModuleRegistry.shared.registerLLM(provider), but this API does not exist in the React Native SDK. The correct method is ServiceRegistry.shared.registerLLMProvider(provider). Update the error message to guide users to the actual registration API.

🤖 Prompt for AI Agents
In sdk/runanywhere-react-native/src/Features/LLM/Errors/LLMError.ts around lines
30 to 37, the error message references a non-existent API
ModuleRegistry.shared.registerLLM(provider); update the message to point to the
correct React Native SDK method
ServiceRegistry.shared.registerLLMProvider(provider). Edit the message string
used when modelId is undefined so users are guided to call
ServiceRegistry.shared.registerLLMProvider(provider) instead of the old
ModuleRegistry API.

sanchitmonga22 and others added 9 commits December 21, 2025 14:31
- Updated type parameters in StructuredOutputHandler and DataSource interfaces for improved clarity and consistency.
- Enhanced error handling in SyncCoordinator to ensure remote data source availability before syncing batches.
- Specified type for preferredFramework in LLMGenerationOptions to improve type safety and maintainability.
- Updated SettingsScreen to convert string capabilities to numeric indices for better display mapping.
- Enhanced STT and TTS screens to utilize model categories instead of types for improved clarity.
- Improved error handling in SecureStorageService and DeviceIdentityService by logging errors with structured objects.
- Streamlined type exports and added new type declarations for better type safety across various modules.
- Introduced type declarations for react-native-fs to enhance file handling capabilities.
- Refactored APIClient to handle null access tokens gracefully, ensuring fallback to API key when necessary.
- Updated App.tsx to implement two-phase SDK initialization and module registration for LlamaCPP and ONNX models.
- Added detailed model registration logic for LlamaCPP and ONNX, including multiple model definitions with memory requirements and download URLs.
- Enhanced ChatScreen, STTScreen, TTSScreen, SettingsScreen, and VoiceAssistantScreen with comprehensive architecture descriptions and feature lists, aligning with iOS counterparts.
- Introduced new Modules index file to streamline module exports and improve organization.
- Added LlamaCPP and ONNX module wrappers to provide a consistent API for model registration and management.
- Updated App.tsx to improve SDK initialization with useCallback for better performance.
- Introduced knip.json for managing unused imports and enhancing code quality.
- Refactored multiple components to improve code readability and maintainability by restructuring imports and applying consistent formatting.
- Enhanced package.json and package-lock.json with updated dependencies for better development experience.
- Streamlined type imports across various files to ensure clarity and consistency in type usage.
- Removed obsolete NativeAudioModule to simplify the audio handling structure.
…atures

- Updated SettingsScreen to integrate new SDK API for retrieving storage information and managing downloaded models.
- Refactored VoiceAssistantScreen to implement a complete voice processing pipeline, including audio recording, transcription, LLM response generation, and TTS synthesis.
- Introduced new extensions for Voice Session, Voice Agent, and Storage Management, providing modular capabilities for voice interactions and storage handling.
- Improved error handling and logging throughout the voice processing and storage management functionalities.
- Streamlined imports and exports across the SDK to enhance organization and maintainability.
@sanchitmonga22 sanchitmonga22 changed the base branch from smonga/ios_rearch to dev January 3, 2026 02:01
Resolved Package.resolved conflict by accepting dev branch version.
…new native bridges for enhanced functionality

- Deleted multiple unused capability and service files across core functionalities, including DeviceCapability, TextGeneration, and Analytics.
- Added new native bridges for Android and iOS to improve integration with the RunAnywhere framework.
- Updated package configurations and build scripts to support the new architecture.
@sanchitmonga22 sanchitmonga22 changed the base branch from dev to smonga/android_rearch January 5, 2026 17:53
…abilities

- Added VoiceSession feature module to manage audio capture and playback for voice assistant integration.
- Implemented AudioCaptureManager and AudioPlaybackManager for handling audio recording and playback.
- Created VoiceSessionHandle for high-level voice session management.
- Re-exported new features in the core SDK index for easier access.
- Updated type definitions for voice session events and configurations.
- Removed outdated device registration service and common events definitions from the infrastructure module.
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