cleanup(swift): remove redundant examples and validation projects#443
cleanup(swift): remove redundant examples and validation projects#443josuediazflores wants to merge 1304 commits intoRunanywhereAI:mainfrom
Conversation
- Downgraded 'record' dependency version from ^6.1.2 to ^6.1.0 in pubspec.yaml. - Enhanced error handling for plugin registration in GeneratedPluginRegistrant.java and GeneratedPluginRegistrant.m. - Removed unused ChangeNotifierProvider from runanywhere_ai_app.dart. - Updated model download progress handling in model_manager.dart and model_selection_sheet.dart. - Cleaned up unused code and improved comments across various files for better maintainability. - Added new files for ONNX and LlamaCpp plugins, including their respective podspecs and Gradle configurations. - Removed deprecated native libraries and related files from the project.
- Introduced SDKLogger for structured logging in both iOS and Android. - Replaced print and NSLog statements with SDKLogger methods for consistency. - Added SwiftLint rules to enforce SDKLogger usage in Swift files. - Updated various components to utilize the new logging system, enhancing error tracking and debugging capabilities. - Configured logging settings in package.json to disallow console.log usage, ensuring all logs are routed through SDKLogger.
- Introduced a new Lefthook configuration file for managing Git hooks. - Updated Podfile to use static linkage for RACommons symbols and improved comments for clarity. - Removed deprecated entries from project.pbxproj to streamline the build process. - Enhanced model management in runanywhere_ai_app.dart by simplifying model registration and unloading logic. - Cleaned up unused code and improved comments across various files for better maintainability. - Added new markdown files for Flutter SDK to Swift SDK migration analysis and parity migration plan.
…ed stability - Added a new isolate for LLM generation to prevent heap corruption from C++ background threads. - Introduced a helper class for isolate communication and error handling. - Updated the generate method to utilize the new isolate approach, enhancing performance and reliability.
- Enhanced the LLM generation process to support real-time streaming of tokens using isolates. - Introduced a new `LLMStreamingResult` class to encapsulate the streaming output, final result, and cancellation functionality. - Updated the `generateStream` method to return a stream of tokens and a future for final metrics, allowing for better user interaction and control. - Improved error handling and communication between isolates for robust streaming operations.
- Refactored ModelManager to reduce complexity by removing event listeners and internal state management. - Updated methods to directly interact with the RunAnywhere SDK for model loading, unloading, and state checks. - Enhanced chat and voice features to utilize SDK state directly, improving synchronization and reducing reliance on ModelManager. - Cleaned up unused code and improved comments for better maintainability across various files.
- Added TTS synthesis capabilities in the DartBridgeTTS class, allowing for speech generation from text with customizable rate, pitch, and volume. - Enhanced the TTSResult class to encapsulate audio samples, sample rate, and duration for synthesized speech. - Integrated TTS synthesis into the RunAnywhere class, providing a straightforward API for users to synthesize speech. - Implemented audio playback from synthesized samples, ensuring seamless user experience. - Updated comments and documentation for clarity and maintainability across the TTS-related files.
- Implemented checks for voice agent readiness in the SDK, ensuring all required components (STT, LLM, TTS) are loaded before starting a voice session. - Refactored voice session handling to utilize the new SDK API for starting sessions, improving integration and reliability. - Introduced detailed error handling for voice agent initialization failures, providing clearer feedback to users. - Added new types for voice agent component states, enhancing the API for checking model readiness. - Updated documentation and comments for clarity and maintainability across voice-related files.
- Added a check to determine if audio data is already in WAV format before conversion, enhancing efficiency. - Updated the DartBridgeVoiceAgent to reflect that synthesized audio is now in WAV format, eliminating unnecessary conversions. - Refactored the RunAnywhere class to directly use WAV audio data for playback, streamlining the audio processing workflow. - Improved documentation and comments for clarity regarding audio data handling.
…le files - Streamlined import statements in various files to use package imports for consistency and clarity. - Removed unnecessary export statements and organized the structure of the public API for better maintainability. - Enhanced code readability by applying consistent formatting and indentation in the conversation store and event publisher classes. - Updated comments and documentation to reflect changes and improve understanding of the codebase. - Ensured that fire-and-forget patterns are clearly indicated with unawaited calls in relevant sections.
…rch - resolve conflicts
…native_rearch [React-native] Alignment with iOS architecture
- Add SDKTestApp: minimal iOS test app (Status, Chat, TTS tabs) - List/download/load LLM and TTS models with progress - Chat: send messages and get LLM responses - TTS: speak text with Piper voices - Add swift-spm-example: SPM consumer example - Point swift-spm-example and validation/swift-spm-consumer at RunanywhereAI/runanywhere-sdks - SDK: clearer Foundation Models error messages; RunAnywhereAI README chat/LLM notes
…ge.swift v0.17.5 - swift-auto-tag.yml: auto-tag swift-v* on push to main - swift-sdk-build-release.yml: Phase 2 – build on swift-v* tag, create release + semver tag - swift-sdk-release.yml: tag trigger removed in favor of Phase 2 - Package.swift: remote binaries for v0.17.5 for consumers
Ci/swift cd only
- CppBridge+Device/ModelAssignment: write to temp pointers in Task, copy to outResponse after wait - CppBridge+Platform: TTS create use handlePtr; generate use responsePtr for strdup - AlamofireDownloadService: capture requiresExtraction in local let for Task - LiveTranscriptionSession: use Sendable Ref for onTermination to avoid capturing self
…Swift 6 concurrency
# Conflicts: # Playground/YapRun/YapRunTests/YapRunTests.swift # Playground/YapRun/YapRunUITests/YapRunUITests.swift # Playground/android-use-agent/settings.gradle.kts
Remove redundant directories per Sanchit's review on PR RunanywhereAI#323: - validation/swift-spm-consumer/ (SDK validation done via ios/example app) - examples/swift-spm-example/ (redundant SPM example) - examples/ios/SDKTestApp/ (redundant test app) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Important
Looks good to me! 👍
Reviewed everything up to ece4c5f in 14 seconds. Click for details.
- Reviewed
1755lines of code in16files - Skipped
8files when reviewing. - Skipped posting
0draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
Workflow ID: wflow_uWuKePA2XSOzAgbu
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
📝 WalkthroughWalkthroughAdds Swift SDK CI/CD automation via GitHub Actions workflows for auto-tagging and release builds. Introduces IDE run configurations, build documentation, git hooks example, and new C API headers for ONNX/LlamaCPP backends without modifying existing code logic. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| on: | ||
| push: | ||
| branches: [main] |
There was a problem hiding this comment.
Auto-tagging fires on every push to main, not just Swift changes.
This workflow triggers on every push to main regardless of what changed. In a polyglot monorepo with multiple SDKs (Flutter, React Native, Android, Kotlin, etc.), every unrelated merge to main will create a new swift-v* tag and subsequently trigger the full swift-sdk-build-release.yml macOS build pipeline — even when no Swift SDK files were touched.
Consider adding a paths filter to scope this trigger to Swift-related changes only:
| on: | |
| push: | |
| branches: [main] | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'sdk/runanywhere-swift/**' | |
| - 'sdk/runanywhere-commons/**' |
Without this, every commit to main (documentation fixes, Android SDK updates, etc.) will increment the Swift patch version and kick off a full macOS XCFramework build.
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/swift-auto-tag.yml
Line: 15-17
Comment:
Auto-tagging fires on every push to main, not just Swift changes.
This workflow triggers on every push to `main` regardless of what changed. In a polyglot monorepo with multiple SDKs (Flutter, React Native, Android, Kotlin, etc.), every unrelated merge to `main` will create a new `swift-v*` tag and subsequently trigger the full `swift-sdk-build-release.yml` macOS build pipeline — even when no Swift SDK files were touched.
Consider adding a `paths` filter to scope this trigger to Swift-related changes only:
```suggestion
on:
push:
branches: [main]
paths:
- 'sdk/runanywhere-swift/**'
- 'sdk/runanywhere-commons/**'
```
Without this, every commit to `main` (documentation fixes, Android SDK updates, etc.) will increment the Swift patch version and kick off a full macOS XCFramework build.
How can I resolve this? If you propose a fix, please make it concise.| - name: Commit and Push Package.swift Update | ||
| run: | | ||
| VERSION="${{ steps.version.outputs.version }}" | ||
| TAG="${{ steps.version.outputs.tag }}" | ||
| COMMONS_CHECKSUM="${{ steps.checksums.outputs.commons }}" | ||
| LLAMACPP_CHECKSUM="${{ steps.checksums.outputs.llamacpp }}" | ||
| ONNX_CHECKSUM="${{ steps.checksums.outputs.onnx }}" | ||
|
|
||
| git config user.name "github-actions[bot]" | ||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||
|
|
||
| # Fetch and checkout main (tag checkout is detached HEAD) | ||
| git fetch origin main | ||
| git checkout main | ||
| git pull origin main | ||
|
|
||
| # Apply the same sed updates to Package.swift on main | ||
| sed -i '' 's/let useLocalBinaries = true/let useLocalBinaries = false/' Package.swift | ||
| sed -i '' 's/let sdkVersion = "[^"]*"/let sdkVersion = "'"$VERSION"'"/' Package.swift | ||
| sed -i '' '/RACommons-ios-v.*zip/,/checksum:/ s/checksum: "[^"]*"/checksum: "'"$COMMONS_CHECKSUM"'"/' Package.swift | ||
| sed -i '' '/RABackendLLAMACPP-ios-v.*zip/,/checksum:/ s/checksum: "[^"]*"/checksum: "'"$LLAMACPP_CHECKSUM"'"/' Package.swift | ||
| sed -i '' '/RABackendONNX-ios-v.*zip/,/checksum:/ s/checksum: "[^"]*"/checksum: "'"$ONNX_CHECKSUM"'"/' Package.swift | ||
|
|
||
| git add Package.swift | ||
| if git diff --staged --quiet; then | ||
| echo "No Package.swift changes to commit" | ||
| else | ||
| git commit -m "chore(swift): update Package.swift checksums for swift-v${VERSION}" | ||
| git push origin main | ||
| fi | ||
|
|
||
| # Create/update tags on this commit | ||
| git push origin ":refs/tags/${TAG}" 2>/dev/null || true | ||
| git tag -f "${TAG}" -m "Swift SDK Release ${TAG}" | ||
| git push origin "${TAG}" | ||
| echo "Tag ${TAG} updated to point to commit with correct checksums" |
There was a problem hiding this comment.
Direct push to main may be blocked by branch protection rules.
This step checks out main and pushes directly to it (git push origin main) from within CI. If the repository has branch protection rules requiring PRs or signed commits, this push will fail and leave the release in a broken half-completed state — the GitHub Release will have been created (next step) but Package.swift will have stale checksums on main.
Additionally, there is a potential race condition: if another PR is merged between git pull origin main (line ~107) and git push origin main (line ~121), the push will fail with a non-fast-forward error.
Consider either:
- Enabling "Allow GitHub Actions to create and approve pull requests" and opening a PR for the
Package.swiftupdate, or - Using a separate branch (e.g.,
chore/swift-checksums-update) that auto-merges, or - Ensuring the repository grants the
contents: writepermission with an appropriate bypass for branch protection on this bot account.
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/swift-sdk-build-release.yml
Line: 93-128
Comment:
Direct push to `main` may be blocked by branch protection rules.
This step checks out `main` and pushes directly to it (`git push origin main`) from within CI. If the repository has branch protection rules requiring PRs or signed commits, this push will fail and leave the release in a broken half-completed state — the GitHub Release will have been created (next step) but `Package.swift` will have stale checksums on `main`.
Additionally, there is a potential race condition: if another PR is merged between `git pull origin main` (line ~107) and `git push origin main` (line ~121), the push will fail with a non-fast-forward error.
Consider either:
1. Enabling "Allow GitHub Actions to create and approve pull requests" and opening a PR for the `Package.swift` update, or
2. Using a separate branch (e.g., `chore/swift-checksums-update`) that auto-merges, or
3. Ensuring the repository grants the `contents: write` permission with an appropriate bypass for branch protection on this bot account.
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (1)
This empty The Flutter equivalent ( Prompt To Fix With AIThis is a comment left during a code review.
Path: sdk/runanywhere-flutter/packages/runanywhere/ios/.testlocal
Line: 1
Comment:
Local test artifact committed to source control.
This empty `.testlocal` file is a local testing artifact that should not be tracked by git. The root `.gitignore` already acknowledges this pattern and already ignores the equivalent file for the React Native package:
```
sdk/runanywhere-react-native/packages/rag/ios/.testlocal
```
The Flutter equivalent (`sdk/runanywhere-flutter/packages/runanywhere/ios/.testlocal`) should be added to `.gitignore` instead of committed. Please remove this file and add the following line to `.gitignore`:
```suggestion
sdk/runanywhere-flutter/packages/runanywhere/ios/.testlocal
```
How can I resolve this? If you propose a fix, please make it concise. |
There was a problem hiding this comment.
Actionable comments posted: 17
🧹 Nitpick comments (3)
.idea/runConfigurations/5__Build_SDK___Run_Android_App.xml (1)
1-36: Filename does not match configuration purpose.The filename
5__Build_SDK___Run_Android_App.xmlsuggests this configuration builds the SDK and runs the Android app, but the actual configuration is named "5️⃣ Clean All" and runs thecleanAlltask. Consider renaming the file to something like5_Clean_All.xmlto avoid confusion when browsing the file system.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.idea/runConfigurations/5__Build_SDK___Run_Android_App.xml around lines 1 - 36, The file name is misleading; rename the file to reflect the configuration's purpose (e.g., 5_Clean_All.xml) and ensure the configuration remains consistent by verifying the configuration name "5️⃣ Clean All" and the Gradle task value "cleanAll" inside the file still match after renaming; update any references or docs that point to the old filename if present.sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_llm_llamacpp.h (1)
54-55: Consider documenting the -1 special value in the field comment.The default config clarifies that
-1means "all layers on GPU", but users reading only the struct definition may miss this. Documenting special values inline improves API discoverability.📝 Suggested documentation improvement
- /** Number of layers to offload to GPU (Metal on iOS/macOS) */ + /** Number of layers to offload to GPU (Metal on iOS/macOS). -1 = all layers */ int32_t gpu_layers;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_llm_llamacpp.h` around lines 54 - 55, The gpu_layers field in the rac_llm_llamacpp.h struct lacks inline documentation for its special -1 value; update the comment on int32_t gpu_layers to explicitly state that -1 means "offload all layers to GPU (Metal on iOS/macOS)" and, if applicable, mention the default behavior (e.g., -1 by default) so users reading only the struct can discover this without consulting external docs.docs/BUILDING-PROJECT.MD (1)
126-133: Add language specifier to code block.The fenced code block should have a language specified for proper rendering.
📝 Proposed fix
-``` +```text runanywhere-sdks/ │── sdk/ │ └──── runanywhere-kotlin/ └── examples/ ├── android/ └── intellij-plugin-demo/</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@docs/BUILDING-PROJECT.MDaround lines 126 - 133, Add a language specifier to
the fenced code block that contains the directory tree (the block beginning with
the line "runanywhere-sdks/") so it renders correctly; update the opening fence
fromto something liketext (or ```bash/plain) to explicitly mark the
block language for the tree snippet.</details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/swift-auto-tag.yml:
- Around line 57-73: The "Skip If Tag Exists" step currently checks only local
refs (git rev-parse) and can race across concurrent runs; add a workflow-level
concurrency key to serialize tag creation and replace the local-only check with
a remote-aware check using git ls-remote --tags origin "$NEW_TAG" (still falling
back to local rev-parse if desired) when computing NEW_TAG from
steps.next_tag.outputs.tag; also ensure the "Create and Push Tag" step (the run
that tags and pushes NEW_TAG) only runs when the remote check indicates the tag
doesn't exist so concurrent runs won't both attempt to push the same tag.In @.github/workflows/swift-sdk-build-release.yml:
- Around line 63-85: The packaging step may skip creating some XCFramework zips
but the Compute Checksums step assumes all three zips exist
(RACommons-ios-v${VERSION}.zip, RABackendLLAMACPP-ios-v${VERSION}.zip,
RABackendONNX-ios-v${VERSION}.zip), causing a later confusing failure; after the
packaging loop in the Prepare Release Assets block (use symbols COMMONS_DIST,
release-assets, VERSION, and the framework names RACommons, RABackendLLAMACPP,
RABackendONNX) add an explicit existence check for each expected zip and if any
are missing call exit 1 with a clear error message (or alternatively record
which zips exist and only compute checksums for those in Compute Checksums using
the corresponding COMMONS_CHECKSUM/LLAMACPP_CHECKSUM/ONNX_CHECKSUM variables),
so failures are deterministic and reported immediately.- Around line 93-133: The workflow currently pushes tags and updates main (the
git push/gite tag/tag -f steps that operate on ${TAG} and ${VERSION}) which
retriggers .github/workflows/swift-auto-tag.yml; either prevent the bot from
triggering that workflow by adding an if condition (e.g., add if: github.actor
!= 'github-actions[bot]' to the tag job or the "Create and Push Tag" step in
swift-auto-tag.yml) or remove the tag mutation block in this workflow that runs
the commands pushing and force-updating ${TAG} (the git push origin
":refs/tags/${TAG}" / git tag -f "${TAG}" / git push origin "${TAG}" sequence)
and rely only on the semver tag (${VERSION}) for SPM resolution to avoid
recursive runs.- Around line 40-42: The workflow uses mutable action tags (actions/checkout@v4
and softprops/action-gh-release@v2) which weakens supply-chain integrity;
replace these references with their corresponding immutable commit SHAs while
retaining the human-readable version as a comment (e.g., use the full commit SHA
for actions/checkout and softprops/action-gh-release and add a trailing comment
like "# v4" or "# v2" for clarity), ensuring both action steps in the YAML are
updated to point to exact commit SHAs.In
@CLAUDE.md:
- Around line 278-281: Remove the duplicate "Known Issues - Xcode 16 Sandbox"
section by locating the repeated header text "Known Issues - Xcode 16 Sandbox"
(and the following lines containing the rsync deny(1) message and fix
instruction "./fix_pods_sandbox.sh") and deleting the redundant occurrence so
only the original section remains; ensure any surrounding spacing or
numbering/TOC references remain consistent after removal.- Around line 852-937: The file contains a duplicated "Kotlin Multiplatform
(KMP) SDK - Critical Implementation Rules" section; remove the second/duplicate
occurrence of that entire section (the repeated block starting with the heading
"Kotlin Multiplatform (KMP) SDK - Critical Implementation Rules" and its
subsections such as Core Principles, Implementation Process, Common Mistakes to
AVOID, and Example) so only the original section remains, and verify any
internal references/TOC entries still point to the single retained section
title.In
@docs/BUILDING-PROJECT.MD:
- Around line 139-142: Update the SDK AAR path string in BUILDING-PROJECT.MD:
replace the incorrect leading "RunAnywhereAI/sdk/runanywhere-kotlin/..." with
"sdk/runanywhere-kotlin/build/outputs/aar/" so the listed SDK AAR path matches
the project structure; locate the line containing "SDK AAR:
RunAnywhereAI/sdk/runanywhere-kotlin/build/outputs/aar/" and edit it to "SDK
AAR:sdk/runanywhere-kotlin/build/outputs/aar/".- Around line 88-97: The docs show non-existent Gradle tasks checkEnvironment
and setupLocalProperties; replace those two lines with the correct combined task
invocation ./gradlew setup (leave the cleanAll line as-is) so the snippet uses
./gradlew setup instead of ./gradlew checkEnvironment and ./gradlew
setupLocalProperties; update the comment above to reflect "Check environment and
setup configuration files" referencing the task names checkEnvironment,
setupLocalProperties and setup to locate the lines to change.- Around line 105-115: Update the docs to show the full Gradle task path or the
correct working-directory context: replace the unqualified ./gradlew
downloadJniLibs with the fully qualified ./gradlew
:runanywhere-kotlin:downloadJniLibs (or instruct users to cd into
sdk/runanywhere-kotlin/ and run ./gradlew downloadJniLibs); also add a note in
the root build.gradle.kts comment block listing downloadJniLibs as an available
user-facing task if it should be advertised from the repo root. Ensure
references to the task name downloadJniLibs and the subproject build.gradle.kts
(sdk/runanywhere-kotlin/build.gradle.kts) are included so readers know where the
task is defined.- Around line 15-24: Replace the non-existent Gradle tasks checkEnvironment and
setupLocalProperties with the single existing setup task by changing the two
separate commands to a single ./gradlew setup call (update the section around
the build steps); then locate any references to the downloadJniLibs task and
either correct them to the actual task name used in the build or remove the call
if no equivalent exists, and fix the incorrect path prefix RunAnywhereAI/sdk/ to
the project's actual SDK path (e.g., sdk/ or the real relative path) so the
documentation matches the real build script and project layout.In
@sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_log.h:
- Around line 35-37: Replace the stderr fallback in rac_log.h with a pluggable
native logging route: add a logger callback setter (e.g.,
rac_set_logger_callback) and a rac_log(...) function that calls the registered
callback if present; implement platform-specific default callbacks that call
NSLog on Apple targets and __android_log_print (Logcat) on Android, and only
fall back to stderr if no callback and no platform default is available; update
any internal uses to call rac_log / the callback instead of writing to stderr
directly.- Around line 79-100: The public macros log_debug, log_info, log_warning, and
log_error are too generic and must be renamed to avoid collisions; change them
to rac_log_debug, rac_log_info, rac_log_warning, and rac_log_error respectively,
keeping their implementation calling rac_log_impl(RAC_LOG_, category,
VA_ARGS) and preserving the existing comments; update any references to the
old macro names in the codebase to the new rac_-prefixed names so compilation
and behavior remain unchanged.- Around line 63-65: The logging call prints level_str/category and then
vfprintf with format/args without NULL checks; guard the pointers before
printing in the log helper (the function using level_str, category, format, args
in rac_log.h) by substituting safe defaults: if category is NULL use a literal
like "(null)" for the %s in fprintf, and if format is NULL skip vfprintf or
replace it with a safe "%s" and an empty string; ensure args is only used when
format is non-NULL so vfprintf is not called with a NULL format pointer.In
@sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_stt_onnx.h:
- Around line 66-93: Add clear C API documentation comments above the streaming
functions (rac_stt_onnx_create_stream, rac_stt_onnx_feed_audio,
rac_stt_onnx_stream_is_ready, rac_stt_onnx_decode_stream,
rac_stt_onnx_input_finished, rac_stt_onnx_is_endpoint,
rac_stt_onnx_destroy_stream) describing the lifecycle (who creates and must
destroy streams), thread-safety expectations, and error semantics; explicitly
state the ownership and free contract for the decoded text returned via char**
out_text in rac_stt_onnx_decode_stream (e.g., caller is responsible for freeing
with free() or provide a library free function), and document when out_text may
be NULL and how memory is allocated/encoded. Ensure the comment style matches
other include/rac/ headers and mention any relevant error codes returned by
rac_result_t.In
@sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_tts_onnx.h:
- Around line 52-61: The header lacks ownership and free-contract docs for
output buffers returned by rac_tts_onnx_synthesize and rac_tts_onnx_get_voices;
update the declarations for rac_tts_onnx_create, rac_tts_onnx_synthesize,
rac_tts_onnx_get_voices (and any vtable/free helpers) to include clear comments
that state who allocates and who must free: e.g., specify that
rac_tts_onnx_synthesize fills a caller-allocated rac_tts_result_t* whose
internal buffers are heap-allocated by the library and must be released via a
new or existing API (add/mention rac_tts_onnx_free_result); likewise document
that rac_tts_onnx_get_voices returns a char** owned by the library and must be
freed with rac_tts_onnx_free_voices (and that out_count is the number of
strings), and document lifetime of rac_handle_t (that it must be destroyed with
rac_tts_onnx_destroy or similar). Include exact function names
(rac_tts_onnx_synthesize, rac_tts_onnx_get_voices, rac_tts_onnx_create,
rac_tts_onnx_free_result, rac_tts_onnx_free_voices, rac_tts_onnx_destroy) in the
comments so FFI users know allocation/free responsibilities.- Around line 45-46: The static const initializer RAC_TTS_ONNX_CONFIG_DEFAULT
for type rac_tts_onnx_config_t uses C-style designated initializers (e.g.,
.num_threads = ...) which are invalid under C++17; replace the designated-field
form with a positional initializer listing fields in the struct order (e.g., {0,
RAC_TRUE, 22050}) in rac_tts_onnx.h and apply the same positional-initializer
refactor to other public headers that define similar constants
(rac_diffusion_types.h, rac_vlm_types.h, rac_stt_types.h, rac_vad_types.h, etc.)
so all static const instances use positional syntax compatible with C++17 while
preserving the original field values and ordering.In
@sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_vad_onnx.h:
- Around line 53-78: Add concise API documentation comments to the public VAD
ONNX declarations (rac_vad_onnx_create, rac_vad_onnx_process,
rac_vad_onnx_start, rac_vad_onnx_stop, rac_vad_onnx_reset,
rac_vad_onnx_set_threshold, rac_vad_onnx_is_speech_active, rac_vad_onnx_destroy,
rac_backend_onnx_register, rac_backend_onnx_unregister) describing: the expected
object lifecycle and valid call order (create -> start -> process -> stop/reset
-> destroy), required preconditions for each call (e.g., handle non-NULL and
started state for rac_vad_onnx_process), return semantics and which rac_result_t
codes may be returned on error, thread-safety guarantees, and side-effects
(e.g., rac_vad_onnx_reset clears internal state, set_threshold affects
subsequent process calls), so callers know error semantics and sequencing for
all public FFI entry points.
Nitpick comments:
In @.idea/runConfigurations/5__Build_SDK___Run_Android_App.xml:
- Around line 1-36: The file name is misleading; rename the file to reflect the
configuration's purpose (e.g., 5_Clean_All.xml) and ensure the configuration
remains consistent by verifying the configuration name "5️⃣ Clean All" and the
Gradle task value "cleanAll" inside the file still match after renaming; update
any references or docs that point to the old filename if present.In
@docs/BUILDING-PROJECT.MD:
- Around line 126-133: Add a language specifier to the fenced code block that
contains the directory tree (the block beginning with the line
"runanywhere-sdks/") so it renders correctly; update the opening fence fromto something liketext (or ```bash/plain) to explicitly mark the block
language for the tree snippet.In
@sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_llm_llamacpp.h:
- Around line 54-55: The gpu_layers field in the rac_llm_llamacpp.h struct lacks
inline documentation for its special -1 value; update the comment on int32_t
gpu_layers to explicitly state that -1 means "offload all layers to GPU (Metal
on iOS/macOS)" and, if applicable, mention the default behavior (e.g., -1 by
default) so users reading only the struct can discover this without consulting
external docs.</details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>Run configuration</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro **Run ID**: `1bc1ae6f-0175-4d0f-bf6d-bfbeb1bbb287` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 7ed42a7b2acba9017e607fb9a92fc910d8ce3658 and ece4c5f0504524650d73f24eb3ab01672b988349. </details> <details> <summary>⛔ Files ignored due to path filters (8)</summary> * `Playground/on-device-browser-agent/package-lock.json` is excluded by `!**/package-lock.json` * `demo.gif` is excluded by `!**/*.gif` * `docs/screenshots/main-screenshot.jpg` is excluded by `!**/*.jpg` * `examples/ios/RunAnywhereAI/docs/screenshots/chat-interface.png` is excluded by `!**/*.png` * `examples/ios/RunAnywhereAI/docs/screenshots/quiz-flow.png` is excluded by `!**/*.png` * `examples/ios/RunAnywhereAI/docs/screenshots/voice-ai.png` is excluded by `!**/*.png` * `examples/react-native/RunAnywhereAI/.yarn/install-state.gz` is excluded by `!**/.yarn/**`, `!**/*.gz` * `package-lock.json` is excluded by `!**/package-lock.json` </details> <details> <summary>📒 Files selected for processing (16)</summary> * `.github/workflows/swift-auto-tag.yml` * `.github/workflows/swift-sdk-build-release.yml` * `.idea/runConfigurations/1_Build_Android_App.xml` * `.idea/runConfigurations/2_Run_Android_App.xml` * `.idea/runConfigurations/3_Build_IntelliJ_Plugin.xml` * `.idea/runConfigurations/4_Run_IntelliJ_Plugin.xml` * `.idea/runConfigurations/5__Build_SDK___Run_Android_App.xml` * `CLAUDE.md` * `docs/BUILDING-PROJECT.MD` * `lefthook.yml` * `sdk/runanywhere-flutter/packages/runanywhere/ios/.testlocal` * `sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_llm_llamacpp.h` * `sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_log.h` * `sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_stt_onnx.h` * `sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_tts_onnx.h` * `sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_vad_onnx.h` </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| - name: Skip If Tag Exists | ||
| id: skip | ||
| run: | | ||
| NEW_TAG="${{ steps.next_tag.outputs.tag }}" | ||
| if git rev-parse "$NEW_TAG" >/dev/null 2>&1; then | ||
| echo "Tag $NEW_TAG already exists, skipping (idempotent rerun)" | ||
| echo "skip=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "skip=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| - name: Create and Push Tag | ||
| if: steps.skip.outputs.skip != 'true' | ||
| run: | | ||
| NEW_TAG="${{ steps.next_tag.outputs.tag }}" | ||
| git tag -a "$NEW_TAG" -m "Swift SDK Release $NEW_TAG" | ||
| git push origin "$NEW_TAG" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/swift-auto-tag.yml"
echo "Expect no match today (missing concurrency):"
rg -n '^\s*concurrency:' "$FILE" || true
echo ""
echo "Expect local-only check currently present:"
rg -n 'git rev-parse|git ls-remote' "$FILE"Repository: RunanywhereAI/runanywhere-sdks
Length of output: 225
🏁 Script executed:
cat -n .github/workflows/swift-auto-tag.yml | head -80Repository: RunanywhereAI/runanywhere-sdks
Length of output: 3026
Harden against concurrent runs creating the same tag.
Line 61 checks only local refs (git rev-parse), so two concurrent runs can both compute the same tag and one will fail at push. Add workflow-level concurrency to serialize tag creation and check remote tag existence (git ls-remote --tags origin ...) instead of local refs.
🔧 Suggested patch
name: Swift SDK Auto-Tag
on:
push:
branches: [main]
+concurrency:
+ group: swift-sdk-auto-tag-main
+ cancel-in-progress: false
+
permissions:
contents: write
@@
- name: Skip If Tag Exists
id: skip
run: |
NEW_TAG="${{ steps.next_tag.outputs.tag }}"
- if git rev-parse "$NEW_TAG" >/dev/null 2>&1; then
+ if git ls-remote --exit-code --tags origin "refs/tags/$NEW_TAG" >/dev/null 2>&1; then
echo "Tag $NEW_TAG already exists, skipping (idempotent rerun)"
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/swift-auto-tag.yml around lines 57 - 73, The "Skip If Tag
Exists" step currently checks only local refs (git rev-parse) and can race
across concurrent runs; add a workflow-level concurrency key to serialize tag
creation and replace the local-only check with a remote-aware check using git
ls-remote --tags origin "$NEW_TAG" (still falling back to local rev-parse if
desired) when computing NEW_TAG from steps.next_tag.outputs.tag; also ensure the
"Create and Push Tag" step (the run that tags and pushes NEW_TAG) only runs when
the remote check indicates the tag doesn't exist so concurrent runs won't both
attempt to push the same tag.
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat .github/workflows/swift-sdk-build-release.ymlRepository: RunanywhereAI/runanywhere-sdks
Length of output: 7814
🌐 Web query:
GitHub Actions pinning commit SHA security best practice 2025
💡 Result:
GitHub Actions “pin to commit SHA” security best practice (2025)
- Pin third-party actions to an immutable ref—preferably a full-length commit SHA (not a moving tag like
v1). This reduces supply-chain risk where a tag/branch could be repointed to malicious code. [1] (wellarchitected.github.com) - Pin SHAs that correspond to a tagged release, and add the version as a comment, so you get immutability and maintainability (humans can see what version you intended). Example:
uses: actions/checkout@<full_sha> # vX.Y.Z. [1] (wellarchitected.github.com) - Verify the SHA comes from the action’s official repository (not a fork/typo-squat). [1] (wellarchitected.github.com)
- Automate updates with Dependabot (GitHub Actions ecosystem) so pinned SHAs don’t become stale; Dependabot will open PRs when newer versions are available. [2] (docs.github.com)
- Enforce SHA pinning centrally with GitHub policy: as of Aug 15, 2025, GitHub added policy support to enforce SHA pinning (workflows fail if an action isn’t pinned) and to block specific actions/versions. [3] (github.blog)
Sources
[1] GitHub Well-Architected: “Securing GitHub Actions Workflows” (wellarchitected.github.com)
[2] GitHub Docs: “Keeping your actions up to date with Dependabot” (docs.github.com)
[3] GitHub Changelog (Aug 15, 2025): “Actions policy now supports blocking and SHA pinning actions” (github.blog)
Citations:
- 1: https://wellarchitected.github.com/library/application-security/recommendations/actions-security/?utm_source=openai
- 2: https://wellarchitected.github.com/library/application-security/recommendations/actions-security/?utm_source=openai
- 3: https://wellarchitected.github.com/library/application-security/recommendations/actions-security/?utm_source=openai
- 4: https://docs.github.com/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/keeping-your-actions-up-to-date-with-dependabot?learn=dependency_version_updates&utm_source=openai
- 5: https://github.blog/changelog/2025-08-15-github-actions-policy-now-supports-blocking-and-sha-pinning-actions/?utm_source=openai
- 6: https://wellarchitected.github.com/library/application-security/recommendations/actions-security/?utm_source=openai
- 7: https://docs.github.com/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/keeping-your-actions-up-to-date-with-dependabot?learn=dependency_version_updates&utm_source=openai
- 8: https://github.blog/changelog/2025-08-15-github-actions-policy-now-supports-blocking-and-sha-pinning-actions/?utm_source=openai
🏁 Script executed:
# Check for all GitHub Actions usage in the workflow
rg "uses:" .github/workflows/swift-sdk-build-release.ymlRepository: RunanywhereAI/runanywhere-sdks
Length of output: 152
Pin GitHub Actions to full commit SHAs.
This release workflow has permissions: contents: write. Using mutable action tags (@v4, @v2) weakens supply-chain integrity. Pin both actions/checkout and softprops/action-gh-release to immutable commit SHAs (with the version number as a comment for readability).
Example
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@<full-commit-sha> # v4
- name: Create GitHub Release
- uses: softprops/action-gh-release@v2
+ uses: softprops/action-gh-release@<full-commit-sha> # v2🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/swift-sdk-build-release.yml around lines 40 - 42, The
workflow uses mutable action tags (actions/checkout@v4 and
softprops/action-gh-release@v2) which weakens supply-chain integrity; replace
these references with their corresponding immutable commit SHAs while retaining
the human-readable version as a comment (e.g., use the full commit SHA for
actions/checkout and softprops/action-gh-release and add a trailing comment like
"# v4" or "# v2" for clarity), ensuring both action steps in the YAML are
updated to point to exact commit SHAs.
| - name: Prepare Release Assets | ||
| id: assets | ||
| run: | | ||
| VERSION="${{ steps.version.outputs.version }}" | ||
| COMMONS_DIST="${COMMONS_DIR}/dist" | ||
| mkdir -p release-assets | ||
| for name in RACommons RABackendLLAMACPP RABackendONNX; do | ||
| if [ -d "${COMMONS_DIST}/${name}.xcframework" ]; then | ||
| zip_name="${name}-ios-v${VERSION}.zip" | ||
| (cd "${COMMONS_DIST}" && zip -r "../../../release-assets/${zip_name}" "${name}.xcframework") | ||
| echo "Created release-assets/${zip_name}" | ||
| fi | ||
| done | ||
| echo "assets_dir=release-assets" >> "$GITHUB_OUTPUT" | ||
| ls -la release-assets/ | ||
|
|
||
| - name: Compute Checksums | ||
| id: checksums | ||
| run: | | ||
| VERSION="${{ steps.version.outputs.version }}" | ||
| COMMONS_CHECKSUM=$(shasum -a 256 "release-assets/RACommons-ios-v${VERSION}.zip" | cut -d ' ' -f 1) | ||
| LLAMACPP_CHECKSUM=$(shasum -a 256 "release-assets/RABackendLLAMACPP-ios-v${VERSION}.zip" | cut -d ' ' -f 1) | ||
| ONNX_CHECKSUM=$(shasum -a 256 "release-assets/RABackendONNX-ios-v${VERSION}.zip" | cut -d ' ' -f 1) |
There was a problem hiding this comment.
Fail fast when expected XCFramework artifacts are missing.
Line 70 conditionally skips zip creation, but Lines 83-85 always compute checksums for all three zips. If one framework is absent, failure happens later and less clearly. Add an explicit artifact check right after packaging.
Proposed guard for deterministic failures
- name: Prepare Release Assets
id: assets
run: |
@@
for name in RACommons RABackendLLAMACPP RABackendONNX; do
if [ -d "${COMMONS_DIST}/${name}.xcframework" ]; then
zip_name="${name}-ios-v${VERSION}.zip"
(cd "${COMMONS_DIST}" && zip -r "../../../release-assets/${zip_name}" "${name}.xcframework")
echo "Created release-assets/${zip_name}"
fi
done
+ for required in RACommons RABackendLLAMACPP RABackendONNX; do
+ test -f "release-assets/${required}-ios-v${VERSION}.zip" || {
+ echo "::error::Missing artifact: release-assets/${required}-ios-v${VERSION}.zip"
+ exit 1
+ }
+ done
echo "assets_dir=release-assets" >> "$GITHUB_OUTPUT"
ls -la release-assets/🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/swift-sdk-build-release.yml around lines 63 - 85, The
packaging step may skip creating some XCFramework zips but the Compute Checksums
step assumes all three zips exist (RACommons-ios-v${VERSION}.zip,
RABackendLLAMACPP-ios-v${VERSION}.zip, RABackendONNX-ios-v${VERSION}.zip),
causing a later confusing failure; after the packaging loop in the Prepare
Release Assets block (use symbols COMMONS_DIST, release-assets, VERSION, and the
framework names RACommons, RABackendLLAMACPP, RABackendONNX) add an explicit
existence check for each expected zip and if any are missing call exit 1 with a
clear error message (or alternatively record which zips exist and only compute
checksums for those in Compute Checksums using the corresponding
COMMONS_CHECKSUM/LLAMACPP_CHECKSUM/ONNX_CHECKSUM variables), so failures are
deterministic and reported immediately.
| - name: Commit and Push Package.swift Update | ||
| run: | | ||
| VERSION="${{ steps.version.outputs.version }}" | ||
| TAG="${{ steps.version.outputs.tag }}" | ||
| COMMONS_CHECKSUM="${{ steps.checksums.outputs.commons }}" | ||
| LLAMACPP_CHECKSUM="${{ steps.checksums.outputs.llamacpp }}" | ||
| ONNX_CHECKSUM="${{ steps.checksums.outputs.onnx }}" | ||
|
|
||
| git config user.name "github-actions[bot]" | ||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||
|
|
||
| # Fetch and checkout main (tag checkout is detached HEAD) | ||
| git fetch origin main | ||
| git checkout main | ||
| git pull origin main | ||
|
|
||
| # Apply the same sed updates to Package.swift on main | ||
| sed -i '' 's/let useLocalBinaries = true/let useLocalBinaries = false/' Package.swift | ||
| sed -i '' 's/let sdkVersion = "[^"]*"/let sdkVersion = "'"$VERSION"'"/' Package.swift | ||
| sed -i '' '/RACommons-ios-v.*zip/,/checksum:/ s/checksum: "[^"]*"/checksum: "'"$COMMONS_CHECKSUM"'"/' Package.swift | ||
| sed -i '' '/RABackendLLAMACPP-ios-v.*zip/,/checksum:/ s/checksum: "[^"]*"/checksum: "'"$LLAMACPP_CHECKSUM"'"/' Package.swift | ||
| sed -i '' '/RABackendONNX-ios-v.*zip/,/checksum:/ s/checksum: "[^"]*"/checksum: "'"$ONNX_CHECKSUM"'"/' Package.swift | ||
|
|
||
| git add Package.swift | ||
| if git diff --staged --quiet; then | ||
| echo "No Package.swift changes to commit" | ||
| else | ||
| git commit -m "chore(swift): update Package.swift checksums for swift-v${VERSION}" | ||
| git push origin main | ||
| fi | ||
|
|
||
| # Create/update tags on this commit | ||
| git push origin ":refs/tags/${TAG}" 2>/dev/null || true | ||
| git tag -f "${TAG}" -m "Swift SDK Release ${TAG}" | ||
| git push origin "${TAG}" | ||
| echo "Tag ${TAG} updated to point to commit with correct checksums" | ||
|
|
||
| # Create semver tag for SPM resolution | ||
| git push origin ":refs/tags/${VERSION}" 2>/dev/null || true | ||
| git tag -f "${VERSION}" -m "Swift SDK v${VERSION}" | ||
| git push origin "${VERSION}" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, list the workflow files
find .github/workflows -type f -name "*.yml" -o -name "*.yaml" | head -20Repository: RunanywhereAI/runanywhere-sdks
Length of output: 619
🏁 Script executed:
# Examine the swift-sdk-build-release.yml file
cat -n .github/workflows/swift-sdk-build-release.yml | head -150Repository: RunanywhereAI/runanywhere-sdks
Length of output: 7388
🏁 Script executed:
# Check if swift-auto-tag.yml exists
cat -n .github/workflows/swift-auto-tag.yml 2>/dev/null || echo "File not found"Repository: RunanywhereAI/runanywhere-sdks
Length of output: 3026
Prevent recursive release runs triggered by main branch pushes.
Line 121 pushes to main after updating Package.swift. This triggers .github/workflows/swift-auto-tag.yml (which runs on push.branches: [main]). That workflow computes and pushes a new swift-v* tag, which immediately matches this workflow's trigger pattern (Lines 22-25), causing this workflow to run again with the newly created tag. This repeats indefinitely.
The suggested [skip ci] in the commit message will not prevent this, as GitHub Actions does not recognize this convention for native branch push triggers.
Add a condition to prevent github-actions[bot] from triggering swift-auto-tag.yml:
In .github/workflows/swift-auto-tag.yml, add an if condition to the tag job or the "Create and Push Tag" step:
if: github.actor != 'github-actions[bot]'Alternatively, remove Lines 125-127 from this workflow (the tag mutation) and rely solely on the semver tag created on Lines 130-133 for SPM resolution, which avoids re-pushing the workflow's trigger tag.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/swift-sdk-build-release.yml around lines 93 - 133, The
workflow currently pushes tags and updates main (the git push/gite tag/tag -f
steps that operate on ${TAG} and ${VERSION}) which retriggers
.github/workflows/swift-auto-tag.yml; either prevent the bot from triggering
that workflow by adding an if condition (e.g., add if: github.actor !=
'github-actions[bot]' to the tag job or the "Create and Push Tag" step in
swift-auto-tag.yml) or remove the tag mutation block in this workflow that runs
the commands pushing and force-updating ${TAG} (the git push origin
":refs/tags/${TAG}" / git tag -f "${TAG}" / git push origin "${TAG}" sequence)
and rely only on the semver tag (${VERSION}) for SPM resolution to avoid
recursive runs.
| #### Known Issues - Xcode 16 Sandbox | ||
| **Error**: `Sandbox: rsync deny(1) file-write-create` | ||
| **Fix**: After `pod install`, run `./fix_pods_sandbox.sh` | ||
|
|
There was a problem hiding this comment.
Duplicate section should be removed.
This "Known Issues - Xcode 16 Sandbox" section is already present at lines 211-214. This appears to be an accidental duplication.
🗑️ Proposed fix: Remove duplicate section
-#### Known Issues - Xcode 16 Sandbox
-**Error**: `Sandbox: rsync deny(1) file-write-create`
-**Fix**: After `pod install`, run `./fix_pods_sandbox.sh`
-
### Pre-commit Hooks📝 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.
| #### Known Issues - Xcode 16 Sandbox | |
| **Error**: `Sandbox: rsync deny(1) file-write-create` | |
| **Fix**: After `pod install`, run `./fix_pods_sandbox.sh` | |
| ### Pre-commit Hooks |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@CLAUDE.md` around lines 278 - 281, Remove the duplicate "Known Issues - Xcode
16 Sandbox" section by locating the repeated header text "Known Issues - Xcode
16 Sandbox" (and the following lines containing the rsync deny(1) message and
fix instruction "./fix_pods_sandbox.sh") and deleting the redundant occurrence
so only the original section remains; ensure any surrounding spacing or
numbering/TOC references remain consistent after removal.
| #define log_debug(category, ...) rac_log_impl(RAC_LOG_DEBUG, category, __VA_ARGS__) | ||
|
|
||
| /** | ||
| * @brief Log an info message. | ||
| * @param category Log category | ||
| * @param ... Printf-style format string and arguments | ||
| */ | ||
| #define log_info(category, ...) rac_log_impl(RAC_LOG_INFO, category, __VA_ARGS__) | ||
|
|
||
| /** | ||
| * @brief Log a warning message. | ||
| * @param category Log category | ||
| * @param ... Printf-style format string and arguments | ||
| */ | ||
| #define log_warning(category, ...) rac_log_impl(RAC_LOG_WARNING, category, __VA_ARGS__) | ||
|
|
||
| /** | ||
| * @brief Log an error message. | ||
| * @param category Log category | ||
| * @param ... Printf-style format string and arguments | ||
| */ | ||
| #define log_error(category, ...) rac_log_impl(RAC_LOG_ERROR, category, __VA_ARGS__) |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Prefix public macros with rac_ to prevent namespace collisions.
log_debug/log_info/log_warning/log_error are globally generic in a public header and can conflict with host apps/libs.
Suggested fix
-#define log_debug(category, ...) rac_log_impl(RAC_LOG_DEBUG, category, __VA_ARGS__)
+#define rac_log_debug(category, ...) rac_log_impl(RAC_LOG_DEBUG, category, __VA_ARGS__)
@@
-#define log_info(category, ...) rac_log_impl(RAC_LOG_INFO, category, __VA_ARGS__)
+#define rac_log_info(category, ...) rac_log_impl(RAC_LOG_INFO, category, __VA_ARGS__)
@@
-#define log_warning(category, ...) rac_log_impl(RAC_LOG_WARNING, category, __VA_ARGS__)
+#define rac_log_warning(category, ...) rac_log_impl(RAC_LOG_WARNING, category, __VA_ARGS__)
@@
-#define log_error(category, ...) rac_log_impl(RAC_LOG_ERROR, category, __VA_ARGS__)
+#define rac_log_error(category, ...) rac_log_impl(RAC_LOG_ERROR, category, __VA_ARGS__)Based on learnings: All public symbols must be prefixed with rac_ (RunAnywhere Commons).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_log.h`
around lines 79 - 100, The public macros log_debug, log_info, log_warning, and
log_error are too generic and must be renamed to avoid collisions; change them
to rac_log_debug, rac_log_info, rac_log_warning, and rac_log_error respectively,
keeping their implementation calling rac_log_impl(RAC_LOG_*, category,
__VA_ARGS__) and preserving the existing comments; update any references to the
old macro names in the codebase to the new rac_*-prefixed names so compilation
and behavior remain unchanged.
| RAC_ONNX_API rac_result_t rac_stt_onnx_create(const char* model_path, | ||
| const rac_stt_onnx_config_t* config, | ||
| rac_handle_t* out_handle); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_stt_onnx_transcribe(rac_handle_t handle, const float* audio_samples, | ||
| size_t num_samples, | ||
| const rac_stt_options_t* options, | ||
| rac_stt_result_t* out_result); | ||
|
|
||
| RAC_ONNX_API rac_bool_t rac_stt_onnx_supports_streaming(rac_handle_t handle); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_stt_onnx_create_stream(rac_handle_t handle, rac_handle_t* out_stream); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_stt_onnx_feed_audio(rac_handle_t handle, rac_handle_t stream, | ||
| const float* audio_samples, size_t num_samples); | ||
|
|
||
| RAC_ONNX_API rac_bool_t rac_stt_onnx_stream_is_ready(rac_handle_t handle, rac_handle_t stream); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_stt_onnx_decode_stream(rac_handle_t handle, rac_handle_t stream, | ||
| char** out_text); | ||
|
|
||
| RAC_ONNX_API void rac_stt_onnx_input_finished(rac_handle_t handle, rac_handle_t stream); | ||
|
|
||
| RAC_ONNX_API rac_bool_t rac_stt_onnx_is_endpoint(rac_handle_t handle, rac_handle_t stream); | ||
|
|
||
| RAC_ONNX_API void rac_stt_onnx_destroy_stream(rac_handle_t handle, rac_handle_t stream); | ||
|
|
||
| RAC_ONNX_API void rac_stt_onnx_destroy(rac_handle_t handle); |
There was a problem hiding this comment.
Specify streaming lifecycle and text ownership contract in the header.
The streaming surface (create_stream/decode_stream/destroy_stream) is public but undocumented for ownership and release rules. In particular, Line 84 (char** out_text) needs an explicit free contract.
📝 Suggested docs for lifecycle + memory ownership
+/**
+ * `@brief` Create a streaming decoder context.
+ *
+ * `@param` handle STT backend handle.
+ * `@param` out_stream Output stream handle; caller must release with rac_stt_onnx_destroy_stream.
+ * `@return` RAC_SUCCESS or error code.
+ */
RAC_ONNX_API rac_result_t rac_stt_onnx_create_stream(rac_handle_t handle, rac_handle_t* out_stream);
+/**
+ * `@brief` Decode current stream state to UTF-8 text.
+ *
+ * `@param` handle STT backend handle.
+ * `@param` stream Stream handle from rac_stt_onnx_create_stream.
+ * `@param` out_text Output text allocated by RAC.
+ * `@return` RAC_SUCCESS or error code.
+ *
+ * `@note` Document exact deallocation function for out_text (e.g., rac_free).
+ */
RAC_ONNX_API rac_result_t rac_stt_onnx_decode_stream(rac_handle_t handle, rac_handle_t stream,
char** out_text);
+/**
+ * `@brief` Destroy a streaming decoder context.
+ *
+ * `@param` handle STT backend handle.
+ * `@param` stream Stream handle to destroy.
+ */
RAC_ONNX_API void rac_stt_onnx_destroy_stream(rac_handle_t handle, rac_handle_t stream);Based on learnings: Public C API headers in include/rac/ must document vtable operations, error codes, and lifecycle requirements.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_stt_onnx.h`
around lines 66 - 93, Add clear C API documentation comments above the streaming
functions (rac_stt_onnx_create_stream, rac_stt_onnx_feed_audio,
rac_stt_onnx_stream_is_ready, rac_stt_onnx_decode_stream,
rac_stt_onnx_input_finished, rac_stt_onnx_is_endpoint,
rac_stt_onnx_destroy_stream) describing the lifecycle (who creates and must
destroy streams), thread-safety expectations, and error semantics; explicitly
state the ownership and free contract for the decoded text returned via char**
out_text in rac_stt_onnx_decode_stream (e.g., caller is responsible for freeing
with free() or provide a library free function), and document when out_text may
be NULL and how memory is allocated/encoded. Ensure the comment style matches
other include/rac/ headers and mention any relevant error codes returned by
rac_result_t.
| static const rac_tts_onnx_config_t RAC_TTS_ONNX_CONFIG_DEFAULT = { | ||
| .num_threads = 0, .use_coreml = RAC_TRUE, .sample_rate = 22050}; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Check C++ language standards in build configurations
rg -n --glob 'CMakeLists.txt' --glob '*.cmake' --glob '*.xcconfig' --glob '*.pbxproj' \
'CMAKE_CXX_STANDARD|cxx_std_|CLANG_CXX_LANGUAGE_STANDARD|-std=c\+\+' || echo "No matches found"
# Also check project.pbxproj more broadly for Swift settings
find . -name "*.pbxproj" -type f 2>/dev/null | head -1 | xargs -I {} grep -n "GCC_CXX_LANGUAGE_STANDARD\|CLANG_CXX_LANGUAGE_STANDARD" {} 2>/dev/null || echo "No xcconfig found"Repository: RunanywhereAI/runanywhere-sdks
Length of output: 4130
🏁 Script executed:
# Verify the exact file exists and show its content
cat -n sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_tts_onnx.h 2>/dev/null || echo "File not found"Repository: RunanywhereAI/runanywhere-sdks
Length of output: 2792
🏁 Script executed:
# Search for ALL designated initializer usage in ONNX public headers
rg -n '\.[A-Za-z_][A-Za-z0-9_]*\s*=' \
sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/ 2>/dev/null || echo "Directory not found"Repository: RunanywhereAI/runanywhere-sdks
Length of output: 38236
C/C++ compatibility issue: designated initializers incompatible with C++17 standard.
Line 46 uses designated initializers (.num_threads = ...), which are only valid in C++20 and later. The primary build targets C++17, causing this to fail when C++ code includes and uses this header's constants. This pattern affects the entire codebase across multiple public headers (rac_diffusion_types.h, rac_vlm_types.h, rac_stt_types.h, rac_vad_types.h, etc.).
Switch to positional initializers to maintain C++17 compatibility:
Recommended fix
static const rac_tts_onnx_config_t RAC_TTS_ONNX_CONFIG_DEFAULT = {
- .num_threads = 0, .use_coreml = RAC_TRUE, .sample_rate = 22050};
+ 0, RAC_TRUE, 22050};This issue exists across the SDK's public headers. A systematic refactor is needed to ensure all static const initializers use positional syntax rather than designated fields.
📝 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.
| static const rac_tts_onnx_config_t RAC_TTS_ONNX_CONFIG_DEFAULT = { | |
| .num_threads = 0, .use_coreml = RAC_TRUE, .sample_rate = 22050}; | |
| static const rac_tts_onnx_config_t RAC_TTS_ONNX_CONFIG_DEFAULT = { | |
| 0, RAC_TRUE, 22050}; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_tts_onnx.h`
around lines 45 - 46, The static const initializer RAC_TTS_ONNX_CONFIG_DEFAULT
for type rac_tts_onnx_config_t uses C-style designated initializers (e.g.,
.num_threads = ...) which are invalid under C++17; replace the designated-field
form with a positional initializer listing fields in the struct order (e.g., {0,
RAC_TRUE, 22050}) in rac_tts_onnx.h and apply the same positional-initializer
refactor to other public headers that define similar constants
(rac_diffusion_types.h, rac_vlm_types.h, rac_stt_types.h, rac_vad_types.h, etc.)
so all static const instances use positional syntax compatible with C++17 while
preserving the original field values and ordering.
| RAC_ONNX_API rac_result_t rac_tts_onnx_create(const char* model_path, | ||
| const rac_tts_onnx_config_t* config, | ||
| rac_handle_t* out_handle); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_tts_onnx_synthesize(rac_handle_t handle, const char* text, | ||
| const rac_tts_options_t* options, | ||
| rac_tts_result_t* out_result); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_tts_onnx_get_voices(rac_handle_t handle, char*** out_voices, | ||
| size_t* out_count); |
There was a problem hiding this comment.
Document ownership/free contract for output buffers.
rac_tts_onnx_synthesize and rac_tts_onnx_get_voices expose output pointers, but the API doesn’t define allocator ownership or exact free sequence. This is a common source of leaks/crashes in C FFI.
📝 Suggested API doc additions
+/**
+ * `@brief` Synthesize speech from text.
+ *
+ * `@param` handle Backend handle from rac_tts_onnx_create.
+ * `@param` text UTF-8 input text.
+ * `@param` options Optional synthesis options (can be NULL for defaults).
+ * `@param` out_result Output result. Caller must release using the standard TTS result free API.
+ * `@return` RAC_SUCCESS or error code.
+ */
RAC_ONNX_API rac_result_t rac_tts_onnx_synthesize(rac_handle_t handle, const char* text,
const rac_tts_options_t* options,
rac_tts_result_t* out_result);
+/**
+ * `@brief` Get available voice IDs.
+ *
+ * `@param` handle Backend handle.
+ * `@param` out_voices Output array of UTF-8 strings allocated by RAC.
+ * `@param` out_count Number of elements in out_voices.
+ * `@return` RAC_SUCCESS or error code.
+ *
+ * `@note` Document exact free contract (e.g., free each string + array via rac_free, or a dedicated free API).
+ */
RAC_ONNX_API rac_result_t rac_tts_onnx_get_voices(rac_handle_t handle, char*** out_voices,
size_t* out_count);Based on learnings: Public C API headers in include/rac/ must document vtable operations, error codes, and lifecycle requirements.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_tts_onnx.h`
around lines 52 - 61, The header lacks ownership and free-contract docs for
output buffers returned by rac_tts_onnx_synthesize and rac_tts_onnx_get_voices;
update the declarations for rac_tts_onnx_create, rac_tts_onnx_synthesize,
rac_tts_onnx_get_voices (and any vtable/free helpers) to include clear comments
that state who allocates and who must free: e.g., specify that
rac_tts_onnx_synthesize fills a caller-allocated rac_tts_result_t* whose
internal buffers are heap-allocated by the library and must be released via a
new or existing API (add/mention rac_tts_onnx_free_result); likewise document
that rac_tts_onnx_get_voices returns a char** owned by the library and must be
freed with rac_tts_onnx_free_voices (and that out_count is the number of
strings), and document lifetime of rac_handle_t (that it must be destroyed with
rac_tts_onnx_destroy or similar). Include exact function names
(rac_tts_onnx_synthesize, rac_tts_onnx_get_voices, rac_tts_onnx_create,
rac_tts_onnx_free_result, rac_tts_onnx_free_voices, rac_tts_onnx_destroy) in the
comments so FFI users know allocation/free responsibilities.
| RAC_ONNX_API rac_result_t rac_vad_onnx_create(const char* model_path, | ||
| const rac_vad_onnx_config_t* config, | ||
| rac_handle_t* out_handle); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_vad_onnx_process(rac_handle_t handle, const float* samples, | ||
| size_t num_samples, rac_bool_t* out_is_speech); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_vad_onnx_start(rac_handle_t handle); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_vad_onnx_stop(rac_handle_t handle); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_vad_onnx_reset(rac_handle_t handle); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_vad_onnx_set_threshold(rac_handle_t handle, float threshold); | ||
|
|
||
| RAC_ONNX_API rac_bool_t rac_vad_onnx_is_speech_active(rac_handle_t handle); | ||
|
|
||
| RAC_ONNX_API void rac_vad_onnx_destroy(rac_handle_t handle); | ||
|
|
||
| // ============================================================================= | ||
| // BACKEND REGISTRATION | ||
| // ============================================================================= | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_backend_onnx_register(void); | ||
|
|
||
| RAC_ONNX_API rac_result_t rac_backend_onnx_unregister(void); |
There was a problem hiding this comment.
Public VAD ONNX APIs need explicit error/lifecycle docs.
These declarations are public FFI entry points, but the header doesn’t define per-call contract details (expected state, error semantics, and lifecycle sequencing such as start/stop/reset usage).
📝 Suggested doc structure for the public VAD ONNX surface
+/**
+ * `@brief` Create ONNX VAD backend instance.
+ *
+ * `@param` model_path Path to VAD model.
+ * `@param` config Optional config (NULL for defaults).
+ * `@param` out_handle Output handle; must be released via rac_vad_onnx_destroy.
+ * `@return` RAC_SUCCESS or error code.
+ */
RAC_ONNX_API rac_result_t rac_vad_onnx_create(const char* model_path,
const rac_vad_onnx_config_t* config,
rac_handle_t* out_handle);
+/**
+ * `@brief` Process audio frame(s).
+ *
+ * `@param` handle VAD handle.
+ * `@param` samples PCM float samples.
+ * `@param` num_samples Number of samples.
+ * `@param` out_is_speech Output speech decision.
+ * `@return` RAC_SUCCESS or error code.
+ */
RAC_ONNX_API rac_result_t rac_vad_onnx_process(rac_handle_t handle, const float* samples,
size_t num_samples, rac_bool_t* out_is_speech);Based on learnings: Public C API headers in include/rac/ must document vtable operations, error codes, and lifecycle requirements.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@sdk/runanywhere-swift/Sources/RunAnywhere/CRACommons/include/rac_vad_onnx.h`
around lines 53 - 78, Add concise API documentation comments to the public VAD
ONNX declarations (rac_vad_onnx_create, rac_vad_onnx_process,
rac_vad_onnx_start, rac_vad_onnx_stop, rac_vad_onnx_reset,
rac_vad_onnx_set_threshold, rac_vad_onnx_is_speech_active, rac_vad_onnx_destroy,
rac_backend_onnx_register, rac_backend_onnx_unregister) describing: the expected
object lifecycle and valid call order (create -> start -> process -> stop/reset
-> destroy), required preconditions for each call (e.g., handle non-NULL and
started state for rac_vad_onnx_process), return semantics and which rac_result_t
codes may be returned on error, thread-safety guarantees, and side-effects
(e.g., rac_vad_onnx_reset clears internal state, set_threshold affects
subsequent process calls), so callers know error semantics and sequencing for
all public FFI entry points.
|
@josuediazflores
Let me know if any questions but will be closing this PR without merging - since I believe these changes are kind of stale/broken. Thanks! |
Summary
Addresses review feedback from @sanchitmonga22 on PR #323 (
ci/swift-cd-only):validation/swift-spm-consumer/— SDK validation is already covered by the iOS example appexamples/swift-spm-example/— redundant SPM exampleexamples/ios/SDKTestApp/— redundant test appThe
friendlyFoundationModelsMessagemethod inCppBridge+Platform.swift(also flagged in the review) was already removed in a previous sync.References
Test plan
CppBridge+Platform.swifthas nofriendlyFoundationModelsMessageorlastFoundationModelsErrorMessage🤖 Generated with Claude Code
Important
Remove redundant Swift directories and add CI/CD workflows for automated tagging and release of Swift SDK.
validation/swift-spm-consumer/,examples/swift-spm-example/, andexamples/ios/SDKTestApp/as they are redundant..github/workflows/swift-auto-tag.ymlto auto-create git tagsswift-vX.Y.Zon merges to main..github/workflows/swift-sdk-build-release.ymlto build and release Swift SDK onswift-v*tag push.friendlyFoundationModelsMessagefromCppBridge+Platform.swift.This description was created by
for ece4c5f. You can customize this summary. It will automatically update as commits are pushed.
Summary by CodeRabbit
New Features
Chores
Greptile Summary
This PR brings over CI/CD automation, documentation, and SDK header files from the
ci/swift-cd-onlybranch (PR #323), omitting the redundant example and validation directories that were flagged in review. The core additions are a two-phase Swift SDK release pipeline:swift-auto-tag.ymlauto-increments and pushes aswift-v*tag on every merge tomain, andswift-sdk-build-release.ymlbuilds XCFrameworks on macOS, computes checksums, updatesPackage.swift, and publishes a GitHub Release.Key issues found:
swift-auto-tag.yml: The workflow triggers on every push tomainwith nopaths:filter. In this polyglot monorepo, every non-Swift merge (Flutter, React Native, Android, etc.) will bump the Swift patch version and kick off a full macOS XCFramework build in Phase 2.maininswift-sdk-build-release.yml: The Package.swift checksum update step checks outmainand pushes directly to it, which will fail if branch protection rules require PRs, and has a race condition if another merge happens concurrently..testlocalfile committed:sdk/runanywhere-flutter/packages/runanywhere/ios/.testlocalis a local test artifact (the root.gitignorealready excludes the identical React Native equivalent). This file should be removed and its pattern added to.gitignore.Confidence Score: 2/5
Last reviewed commit: ece4c5f
Context used:
dashboard- CLAUDE.md (source)