Skip to content

Commit e0fff48

Browse files
updates with dependency updates to the latest
1 parent 41036a4 commit e0fff48

358 files changed

Lines changed: 57087 additions & 45011 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/pr-build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
steps:
3939
- uses: actions/checkout@v4
4040
- uses: actions/setup-node@v4
41-
with: { node-version: '20' }
41+
with: { node-version: '22' }
4242
- name: TypeScript / Web / RN centralization (syncpack)
4343
run: bash scripts/validation/check_typescript_centralization.sh
4444
- name: Flutter dependency centralization
@@ -256,7 +256,7 @@ jobs:
256256
steps:
257257
- uses: actions/checkout@v4
258258
- uses: actions/setup-node@v4
259-
with: { node-version: '20' }
259+
with: { node-version: '22' }
260260
# Repo root and sdk/runanywhere-react-native pin `packageManager: yarn@3.6.1`
261261
# (Yarn Berry). The runner's global yarn is 1.x and refuses to run, so we
262262
# activate the pinned version through Corepack before any `yarn` call.
@@ -286,7 +286,7 @@ jobs:
286286
steps:
287287
- uses: actions/checkout@v4
288288
- uses: actions/setup-node@v4
289-
with: { node-version: '20' }
289+
with: { node-version: '22' }
290290
# Install + typecheck from the workspace root so the in-tree
291291
# @runanywhere/proto-ts package (sdk/shared/proto-ts) is resolved as a
292292
# workspace member instead of being fetched from the npm registry. The

.syncpackrc.json

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
"dependencyTypes": ["dev", "prod", "peer"],
1515
"versionGroups": [
1616
{
17-
"label": "Local workspace packages: ignore (managed by workspaces protocol / peer ranges). NOTE: @runanywhere/proto-ts is a published npm package centralized in dependencies/versions.json, so it is NOT ignored here — see its own pin below.",
17+
"label": "Local workspace packages: ignore (managed by workspaces protocol / peer ranges). @runanywhere/proto-ts lives in sdk/shared/proto-ts and is consumed via workspace:* by all TS SDK packages — it is not published to npm.",
1818
"dependencies": [
1919
"@runanywhere/core",
2020
"@runanywhere/llamacpp",
2121
"@runanywhere/onnx",
2222
"@runanywhere/web",
2323
"@runanywhere/web-llamacpp",
24-
"@runanywhere/web-onnx"
24+
"@runanywhere/web-onnx",
25+
"@runanywhere/proto-ts"
2526
],
2627
"isIgnored": true
2728
},
@@ -91,11 +92,6 @@
9192
"dependencies": ["vite"],
9293
"pinVersion": "^6.4.2"
9394
},
94-
{
95-
"label": "Pinned: @runanywhere/proto-ts (centralized in dependencies/versions.json) — published npm package, schema-sensitive lockstep with all TS SDK packages",
96-
"dependencies": ["@runanywhere/proto-ts"],
97-
"pinVersion": "^0.21.0"
98-
},
9995
{
10096
"label": "Pinned: react-native (centralized in dependencies/versions.json) — Hermes/JSI/NitroModules ABI tracks this version",
10197
"dependencies": ["react-native"],
@@ -139,7 +135,6 @@
139135
"prettier",
140136
"@playwright/test",
141137
"vite",
142-
"@runanywhere/proto-ts",
143138
"@eslint/js",
144139
"tsd"
145140
],

CMakeLists.txt

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,22 @@ set_property(CACHE RAC_SANITIZER PROPERTY STRINGS "" asan tsan ubsan)
8888
# final values before their CMakeLists run. The wasm wrapper target itself
8989
# lives under sdk/runanywhere-web/wasm and is added after the engine targets.
9090
if(EMSCRIPTEN)
91-
option(RAC_WASM_PTHREADS "Enable pthreads in the WebAssembly target" OFF)
92-
option(RAC_WASM_DEBUG "Enable debug assertions/logging in the WebAssembly target" OFF)
93-
option(RAC_WASM_LLAMACPP "Build the WebAssembly target with llama.cpp" OFF)
94-
option(RAC_WASM_VLM "Enable llama.cpp mtmd VLM support in the WebAssembly target" OFF)
95-
option(RAC_WASM_WHISPERCPP "Build the WebAssembly target with whisper.cpp" OFF)
96-
option(RAC_WASM_ONNX "Build the WebAssembly target with ONNX/sherpa support" OFF)
97-
option(RAC_WASM_WEBGPU "Enable WebGPU acceleration for the WebAssembly target" OFF)
91+
option(RAC_WASM_PTHREADS "Enable pthreads in the WebAssembly target" OFF)
92+
option(RAC_WASM_DEBUG "Enable debug assertions/logging in the WebAssembly target" OFF)
93+
option(RAC_WASM_BUILD_CORE "Build the commons-only Web SDK WASM target" OFF)
94+
option(RAC_WASM_LLAMACPP "Build the WebAssembly target with llama.cpp (LLM + VLM)" OFF)
95+
option(RAC_WASM_WHISPERCPP "Build the WebAssembly target with whisper.cpp" OFF)
96+
option(RAC_WASM_ONNX "Build the WebAssembly target with ONNX/sherpa support" OFF)
97+
option(RAC_WASM_WEBGPU "Enable WebGPU acceleration for the WebAssembly target" OFF)
9898

9999
set(RAC_BUILD_JNI OFF CACHE BOOL "" FORCE)
100100
set(RAC_BUILD_TESTS OFF CACHE BOOL "" FORCE)
101101
set(RAC_BUILD_SHARED OFF CACHE BOOL "" FORCE)
102102
set(RAC_BUILD_PLATFORM OFF CACHE BOOL "" FORCE)
103103

104+
# Backends follow the union of requested WASM targets. The core-only target
105+
# never links backend archives, but a configure that ONLY requests core
106+
# still leaves backends off (commons compiles standalone).
104107
if(RAC_WASM_LLAMACPP OR RAC_WASM_WHISPERCPP OR RAC_WASM_ONNX)
105108
set(RAC_BUILD_BACKENDS ON CACHE BOOL "" FORCE)
106109
else()
@@ -111,15 +114,6 @@ if(EMSCRIPTEN)
111114
set(RAC_BACKEND_WHISPERCPP ${RAC_WASM_WHISPERCPP} CACHE BOOL "" FORCE)
112115
set(RAC_BACKEND_ONNX ${RAC_WASM_ONNX} CACHE BOOL "" FORCE)
113116

114-
if(RAC_WASM_VLM AND RAC_WASM_LLAMACPP)
115-
set(RAC_VLM_USE_MTMD ON CACHE BOOL "" FORCE)
116-
else()
117-
if(RAC_WASM_VLM AND NOT RAC_WASM_LLAMACPP)
118-
message(WARNING "RAC_WASM_VLM requires RAC_WASM_LLAMACPP=ON; disabling VLM.")
119-
endif()
120-
set(RAC_VLM_USE_MTMD OFF CACHE BOOL "" FORCE)
121-
endif()
122-
123117
if(RAC_WASM_LLAMACPP OR RAC_WASM_WHISPERCPP)
124118
set(GGML_METAL OFF CACHE BOOL "" FORCE)
125119
set(GGML_VULKAN OFF CACHE BOOL "" FORCE)

engines/llamacpp/CMakeLists.txt

Lines changed: 52 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -146,68 +146,55 @@ set(LLAMACPP_BACKEND_SOURCES
146146
llamacpp_backend.cpp
147147
rac_llm_llamacpp.cpp
148148
rac_backend_llamacpp_register.cpp
149-
# GAP 02 Phase 8: unified engine plugin entry point. Coexists with the
150-
# legacy rac_backend_llamacpp_register() bootstrap; both wrap the same
151-
# ops-struct.
149+
# Unified ABI plugin entry — fills both llm_ops and vlm_ops slots.
152150
rac_plugin_entry_llamacpp.cpp
151+
# VLM Backend (vision-language as a modality of the same engine).
152+
rac_vlm_llamacpp.cpp
153+
# VLM ops vtable (the g_llamacpp_vlm_ops struct consumed by the unified
154+
# plugin entry). Extracted from the (now-deleted) VLM register file when
155+
# the two plugin entries were unified.
156+
rac_llamacpp_vlm_ops.cpp
153157
)
154158

155159
set(LLAMACPP_BACKEND_HEADERS
156160
llamacpp_backend.h
157161
)
158162

159-
# Option to enable VLM multimodal support (requires mtmd from llama.cpp)
160-
option(RAC_VLM_USE_MTMD "Enable VLM multimodal support via llama.cpp mtmd" ON)
161-
if(RAC_VLM_USE_MTMD)
162-
message(STATUS "VLM multimodal support enabled")
163-
# Add VLM Backend sources (Vision Language Model)
164-
list(APPEND LLAMACPP_BACKEND_SOURCES
165-
rac_vlm_llamacpp.cpp
166-
rac_backend_llamacpp_vlm_register.cpp
167-
# GAP 02 Phase 8: unified engine plugin entry point for VLM.
168-
rac_plugin_entry_llamacpp_vlm.cpp
169-
)
170-
# Add mtmd sources from llama.cpp tools directory. mtmd-image.cpp
171-
# carries the `mtmd_image_preprocessor_*` vtables that mtmd.cpp
172-
# references during `mtmd_context::init_vision()`; without it ld.lld
173-
# on Linux/Android complains:
174-
# ld.lld: error: undefined symbol: vtable for
175-
# mtmd_image_preprocessor_{llava_uhd,step3vl,idefics3,internvl}
176-
list(APPEND LLAMACPP_BACKEND_SOURCES
177-
${llamacpp_SOURCE_DIR}/tools/mtmd/mtmd.cpp
178-
${llamacpp_SOURCE_DIR}/tools/mtmd/mtmd-helper.cpp
179-
${llamacpp_SOURCE_DIR}/tools/mtmd/mtmd-audio.cpp
180-
${llamacpp_SOURCE_DIR}/tools/mtmd/mtmd-image.cpp
181-
${llamacpp_SOURCE_DIR}/tools/mtmd/clip.cpp
182-
)
183-
# Glob every mtmd model implementation upstream ships. The previous
184-
# hand-curated list drifts each llama.cpp bump (b9180 adds
185-
# deepseekocr / dotsocr / gemma4a / gemma4v / granite-speech /
186-
# hunyuanocr / mimovl / qwen3a / step3vl / yasa2 over what we
187-
# listed). On Linux/Android the resulting clip_image_build_graph
188-
# references unconditionally need every clip_graph_<name>::* vtable
189-
# to be present at link time, otherwise ld.lld bails with
190-
# ld.lld: error: undefined symbol: vtable for clip_graph_<name>
191-
# `CONFIGURE_DEPENDS` re-globs when the directory changes.
192-
#
193-
# pass2-syn-063: CONFIGURE_DEPENDS is best-effort on Visual Studio /
194-
# Xcode generators (CMake docs: "a generator may not implement this
195-
# feature"). All RAC CMakePresets that build this engine use Ninja
196-
# (macos-debug, macos-release, linux-asan, android-arm64, ios-*),
197-
# so re-glob fires reliably for our CI matrix. Developers who run an
198-
# Xcode-driven CMake build of the C++ engine for direct on-device
199-
# profiling MUST `cmake --reconfigure` after an upstream llama.cpp
200-
# bump that adds a new tools/mtmd/models/*.cpp file; otherwise the
201-
# build fails at link time with an undefined vtable for
202-
# clip_graph_<new_model>. The STATUS message below prints the
203-
# discovered count to make a silent drop loud during local builds.
204-
file(GLOB _RAC_MTMD_MODEL_SOURCES CONFIGURE_DEPENDS
205-
"${llamacpp_SOURCE_DIR}/tools/mtmd/models/*.cpp"
206-
)
207-
list(LENGTH _RAC_MTMD_MODEL_SOURCES _RAC_MTMD_MODEL_COUNT)
208-
message(STATUS "VLM mtmd model implementations discovered: ${_RAC_MTMD_MODEL_COUNT} (llama.cpp ${LLAMACPP_VERSION})")
209-
list(APPEND LLAMACPP_BACKEND_SOURCES ${_RAC_MTMD_MODEL_SOURCES})
210-
endif()
163+
# VLM multimodal support is always compiled in — llama.cpp is one engine
164+
# that supports both LLM and VLM modalities. The two are exposed through
165+
# a single unified plugin vtable, not two separate plugins.
166+
#
167+
# Add mtmd sources from llama.cpp tools directory. mtmd-image.cpp carries
168+
# the `mtmd_image_preprocessor_*` vtables that mtmd.cpp references during
169+
# `mtmd_context::init_vision()`; without it ld.lld on Linux/Android complains:
170+
# ld.lld: error: undefined symbol: vtable for
171+
# mtmd_image_preprocessor_{llava_uhd,step3vl,idefics3,internvl}
172+
list(APPEND LLAMACPP_BACKEND_SOURCES
173+
${llamacpp_SOURCE_DIR}/tools/mtmd/mtmd.cpp
174+
${llamacpp_SOURCE_DIR}/tools/mtmd/mtmd-helper.cpp
175+
${llamacpp_SOURCE_DIR}/tools/mtmd/mtmd-audio.cpp
176+
${llamacpp_SOURCE_DIR}/tools/mtmd/mtmd-image.cpp
177+
${llamacpp_SOURCE_DIR}/tools/mtmd/clip.cpp
178+
)
179+
180+
# Glob every mtmd model implementation upstream ships. The hand-curated list
181+
# drifts each llama.cpp bump (b9180 adds deepseekocr / dotsocr / gemma4a /
182+
# gemma4v / granite-speech / hunyuanocr / mimovl / qwen3a / step3vl / yasa2
183+
# etc.). On Linux/Android the resulting clip_image_build_graph references
184+
# unconditionally need every clip_graph_<name>::* vtable to be present at
185+
# link time, otherwise ld.lld bails with
186+
# ld.lld: error: undefined symbol: vtable for clip_graph_<name>
187+
# `CONFIGURE_DEPENDS` re-globs when the directory changes; it is best-effort
188+
# on Visual Studio / Xcode generators but reliable on Ninja (which RAC's
189+
# CMakePresets use). Developers running an Xcode-driven CMake build for
190+
# on-device profiling MUST `cmake --reconfigure` after an upstream llama.cpp
191+
# bump that adds a new tools/mtmd/models/*.cpp file.
192+
file(GLOB _RAC_MTMD_MODEL_SOURCES CONFIGURE_DEPENDS
193+
"${llamacpp_SOURCE_DIR}/tools/mtmd/models/*.cpp"
194+
)
195+
list(LENGTH _RAC_MTMD_MODEL_SOURCES _RAC_MTMD_MODEL_COUNT)
196+
message(STATUS "VLM mtmd model implementations discovered: ${_RAC_MTMD_MODEL_COUNT} (llama.cpp ${LLAMACPP_VERSION})")
197+
list(APPEND LLAMACPP_BACKEND_SOURCES ${_RAC_MTMD_MODEL_SOURCES})
211198

212199
# GAP 06 close-out (Phase 1 / B1): migrated to rac_add_engine_plugin().
213200
#
@@ -257,41 +244,32 @@ rac_add_engine_plugin(llamacpp
257244
${llamacpp_SOURCE_DIR}/ggml/include
258245
${llamacpp_SOURCE_DIR}/vendor # nlohmann/json.hpp
259246
COMPILE_DEFINITIONS RAC_LLAMACPP_BUILDING
260-
PRIMITIVES GENERATE_TEXT
247+
PRIMITIVES GENERATE_TEXT VLM
261248
RUNTIMES CPU METAL CUDA
262249
FORMATS GGUF GGML BIN
263250
AVAILABILITY PUBLIC
264251
PACKAGE_OWNER runanywhere
265252
PACKAGE_NAME runanywhere_llamacpp
266253
)
267254

268-
# VLM multimodal mtmd includes/defs — engine-specific, applied after the macro.
269-
if(RAC_VLM_USE_MTMD)
270-
target_include_directories(rac_backend_llamacpp PRIVATE
271-
${llamacpp_SOURCE_DIR}/tools/mtmd
272-
${llamacpp_SOURCE_DIR}/tools/mtmd/models
273-
)
274-
target_compile_definitions(rac_backend_llamacpp PRIVATE RAC_VLM_USE_MTMD=1)
275-
endif()
255+
# VLM multimodal mtmd includes — engine-specific, applied after the macro.
256+
# mtmd is always compiled in (one engine, two modalities).
257+
target_include_directories(rac_backend_llamacpp PRIVATE
258+
${llamacpp_SOURCE_DIR}/tools/mtmd
259+
${llamacpp_SOURCE_DIR}/tools/mtmd/models
260+
)
276261

277262
# Self-registration carrier: thin shim that wraps RAC_STATIC_PLUGIN_REGISTER.
263+
# Since llama.cpp is one engine with both LLM and VLM modalities exposed by
264+
# the same plugin vtable, there is a single static-register shim and a single
265+
# SHARED carrier (no separate _vlm variants).
278266
if(RAC_STATIC_PLUGINS)
279267
# Static path: ctor lands inside rac_commons so it runs before main().
280268
# rac_commons PUBLIC-links rac_backend_llamacpp below so the entry
281269
# symbol resolves at link time.
282270
target_sources(rac_commons PRIVATE
283271
${CMAKE_CURRENT_SOURCE_DIR}/rac_static_register_llamacpp.cpp
284272
)
285-
if(RAC_VLM_USE_MTMD)
286-
# Swift-only E2E Phase 6e: VLM plugin needs its own static-register
287-
# ctor to be routable via rac_plugin_route(framework=llamacpp,
288-
# primitive=vlm). Without this, only the LLM plugin registers at
289-
# process start and VLM loads fail with
290-
# "no backend route for llamacpp_vlm".
291-
target_sources(rac_commons PRIVATE
292-
${CMAKE_CURRENT_SOURCE_DIR}/rac_static_register_llamacpp_vlm.cpp
293-
)
294-
endif()
295273
target_include_directories(rac_commons PRIVATE
296274
${CMAKE_CURRENT_SOURCE_DIR}
297275
${RAC_COMMONS_ROOT_DIR}/include
@@ -313,33 +291,6 @@ else()
313291
)
314292
rac_apply_android_page_alignment(runanywhere_llamacpp)
315293
install(TARGETS runanywhere_llamacpp LIBRARY DESTINATION lib)
316-
317-
if(RAC_VLM_USE_MTMD)
318-
# Parallel SHARED carrier for the VLM vtable so dynamic-plugin hosts
319-
# can route RAC_PRIMITIVE_VLM (name="llamacpp_vlm") via
320-
# `rac_registry_load_plugin(librunanywhere_llamacpp_vlm.*)`. The
321-
# dlopen loader derives the entry-symbol name from the library
322-
# filename (see plugin_loader.cpp::entry_symbol_from_path), so the
323-
# carrier's basename must match `runanywhere_llamacpp_vlm` to map to
324-
# `rac_plugin_entry_llamacpp_vlm`. Without this, a host that does NOT
325-
# call `rac_backend_llamacpp_vlm_register()` directly (the Swift /
326-
# Kotlin / RN bridge path) cannot reach the VLM plugin even though
327-
# the implementation is linked into rac_backend_llamacpp.
328-
add_library(runanywhere_llamacpp_vlm SHARED
329-
${CMAKE_CURRENT_SOURCE_DIR}/rac_static_register_llamacpp_vlm.cpp
330-
)
331-
set_target_properties(runanywhere_llamacpp_vlm PROPERTIES
332-
OUTPUT_NAME runanywhere_llamacpp_vlm
333-
C_VISIBILITY_PRESET hidden
334-
CXX_VISIBILITY_PRESET hidden
335-
)
336-
target_link_libraries(runanywhere_llamacpp_vlm PUBLIC
337-
rac_backend_llamacpp
338-
rac_commons
339-
)
340-
rac_apply_android_page_alignment(runanywhere_llamacpp_vlm)
341-
install(TARGETS runanywhere_llamacpp_vlm LIBRARY DESTINATION lib)
342-
endif()
343294
endif()
344295

345296
# =============================================================================

engines/llamacpp/jni/rac_backend_llamacpp_jni.cpp

Lines changed: 7 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ static const char *LOG_TAG = "JNI.LlamaCpp";
3030
#define LOGe(...) RAC_LOG_ERROR(LOG_TAG, __VA_ARGS__)
3131
#define LOGw(...) RAC_LOG_WARNING(LOG_TAG, __VA_ARGS__)
3232

33-
// Forward declaration for registration functions
33+
// Forward declaration for the unified registration function. After the
34+
// LLM/VLM plugin unification, llama.cpp publishes ONE plugin that fills
35+
// both `llm_ops` and `vlm_ops` slots; there is no separate VLM register.
3436
extern "C" rac_result_t rac_backend_llamacpp_register(void);
3537
extern "C" rac_result_t rac_backend_llamacpp_unregister(void);
36-
extern "C" rac_result_t rac_backend_llamacpp_vlm_register(void);
37-
extern "C" rac_result_t rac_backend_llamacpp_vlm_unregister(void);
3838

3939
extern "C" {
4040

@@ -118,56 +118,13 @@ Java_com_runanywhere_sdk_llm_llamacpp_LlamaCPPBridge_nativeGetVersion(
118118
return env->NewStringUTF(RAC_LLAMACPP_VERSION);
119119
}
120120

121-
// =============================================================================
122-
// VLM Backend Registration
123-
// =============================================================================
124-
125-
/**
126-
* Register the LlamaCPP VLM backend with the C++ service registry.
127-
* Mirrors iOS LlamaCPP.registerVLM() pattern.
128-
*/
129-
JNIEXPORT jint JNICALL
130-
Java_com_runanywhere_sdk_llm_llamacpp_LlamaCPPBridge_nativeRegisterVlm(
131-
JNIEnv *env, jclass clazz) {
132-
(void)env;
133-
(void)clazz;
134-
LOGi("LlamaCPP nativeRegisterVlm called");
135-
136-
rac_result_t result = rac_backend_llamacpp_vlm_register();
137-
138-
if (result != RAC_SUCCESS && result != RAC_ERROR_MODULE_ALREADY_REGISTERED) {
139-
LOGe("Failed to register LlamaCPP VLM backend: %d", result);
140-
return static_cast<jint>(result);
141-
}
142-
143-
LOGi("LlamaCPP VLM backend registered successfully");
144-
return RAC_SUCCESS;
145-
}
146-
147-
/**
148-
* Unregister the LlamaCPP VLM backend from the C++ service registry.
149-
*/
150-
JNIEXPORT jint JNICALL
151-
Java_com_runanywhere_sdk_llm_llamacpp_LlamaCPPBridge_nativeUnregisterVlm(
152-
JNIEnv *env, jclass clazz) {
153-
(void)env;
154-
(void)clazz;
155-
LOGi("LlamaCPP nativeUnregisterVlm called");
156-
157-
rac_result_t result = rac_backend_llamacpp_vlm_unregister();
158-
159-
if (result != RAC_SUCCESS) {
160-
LOGe("Failed to unregister LlamaCPP VLM backend: %d", result);
161-
} else {
162-
LOGi("LlamaCPP VLM backend unregistered");
163-
}
164-
165-
return static_cast<jint>(result);
166-
}
167-
168121
// =============================================================================
169122
// LLM Operations - Direct API calls
170123
// =============================================================================
124+
// Note: VLM registration is no longer a separate JNI call. After the LLM/VLM
125+
// plugin unification, `rac_backend_llamacpp_register()` registers ONE plugin
126+
// vtable with both LLM and VLM ops filled. Kotlin's `LlamaCPP.register()`
127+
// calls `nativeRegister()` once; both modalities light up together.
171128

172129
/**
173130
* Create a LlamaCPP instance and load a model

0 commit comments

Comments
 (0)