Mobile Bindings Overview¶
Status: in progress; corpus bindings are the primary scope
Goals¶
- Provide a minimal C ABI for corpus access without leaking internal C++ types.
- Enable embedders to build thin Swift/Kotlin/Flutter wrappers on top of a shared library (
libyams_mobile). - Maintain binary compatibility across minor releases via versioned structs and feature flags.
Product Boundary¶
The current intended split is:
libyams_mobileowns corpus access: context lifecycle, ingest, update/delete, list/search/get, metadata, and graph retrieval where supported.- The host app owns the LLM runtime and chat UX: model download/load, prompt assembly, generation, streaming responses, tool orchestration, and conversation presentation.
This means mobile bindings should be evaluated as a corpus SDK, not as an inference SDK.
Target Platforms¶
- iOS 15+/macOS 13+ (Swift Package Manager integration)
- Android API 26+ (AAR with JNI bindings)
- Additional consumers via C-compatible dynamic libraries (e.g., React Native, Flutter)
Architectural Shape¶
- Core ABI Layer — versioned header
include/yams/api/mobile_bindings.hcompiled intolibyams_mobile. - Platform Glue — Swift/Kotlin wrappers (future milestone) translate native types and may layer async semantics over the blocking C entrypoints.
- Service Facade — long-lived
yams_mobile_context_tmapping toAppContextwith configurable storage paths, caches, and worker executors. - Lifecycle Hooks — initialization, shutdown, and JSON-based diagnostics helpers.
[Swift/Combine] [Kotlin/Coroutines]
\ /
\ yams_mobile C ABI /
\ /
Core corpus services (ingest/search/get + fixture-driven corpora)
Data Model Principles¶
- All structs are POD with explicit sizes; optional fields are represented via nullable pointers or sentinel flags.
- Strings use UTF-8
char*with caller-managed allocation; response containers return opaque handles with dispose functions. - Errors propagate through
yams_mobile_statusenums plus optional extended payloads.
Threading & Concurrency¶
- Embedders may call APIs from any thread; the library owns a background
boost::asio::thread_poolper context. - The current C ABI exposes synchronous entrypoints only (
yams_mobile_*_execute). Async helpers will ship with platform wrappers. - Swift/Kotlin adapters should wrap the blocking calls using dispatch queues/coroutines to surface async behaviour.
Responsibility Split¶
In Scope For Bindings¶
- Open and manage a local YAMS corpus context.
- Store and update documents, tags, and metadata.
- Retrieve context for prompt assembly through list/search/get APIs.
- Expose graph and metadata inspection where the backend supports it.
- Return stable JSON payloads suitable for thin platform wrappers.
Out Of Scope For Bindings¶
- Hosting Gemma or any other local model.
- Chat session state, streaming token output, or response rendering.
- Model lifecycle UX such as download progress, preload controls, and provider settings.
- App-side ranking, prompt composition, or summarization policy beyond raw corpus retrieval.
Feature Skeleton¶
| Area | Available entrypoints | Notes |
|---|---|---|
| Context lifecycle | yams_mobile_context_create, yams_mobile_context_destroy |
Config accepts working/cache dirs and a telemetry_sink string (console, stderr, noop, or file:/path). |
| Grep/Search | yams_mobile_grep_execute, yams_mobile_search_execute, destroy helpers, yams_mobile_{grep,search}_result_stats_json |
Blocking calls returning opaque handles plus JSON stats (latency, retry counters). |
| Document lifecycle | yams_mobile_store_document, yams_mobile_download, yams_mobile_update_document, yams_mobile_delete_by_name, yams_mobile_remove_document |
CRUD exists; delete APIs now align on the common status/payload contract across embedded and daemon mode. Naming cleanup is still in progress. |
| Document retrieval | yams_mobile_list_documents, yams_mobile_get_document |
Core surface for app-side prompt assembly and memory recall; list_documents and get_document now return stable JSON payloads across embedded and daemon mode. |
| Metadata inspection | yams_mobile_get_metadata, yams_mobile_metadata_result_json |
JSON payload mirrors DocumentService metadata map. |
| Graph retrieval | yams_mobile_graph_query, yams_mobile_graph_query_result_json |
Supported in both daemon and embedded mode for corpus-backed documents; follow-up parity review is still needed for edge cases and cleanup behavior. |
| Corpus status | yams_mobile_get_vector_status, yams_mobile_vector_status_result_json |
JSON now reports corpus/index readiness, embedding coverage, and corpus feature signals. The request-side warmup flag is deprecated and ignored for ABI compatibility. |
Current Gaps¶
- Embedded and daemon backends do not yet expose identical behavior for all corpus APIs.
get_document.include_contentparity is fixed and covered by daemon/mobile tests, but other corpus APIs still need backend-by-backend review.list_documentsnow returns a stable top-level/document JSON shape in both embedded and daemon mode for the common non-paths_onlycorpus flow.search_executenow returns a stable top-level/result JSON shape in both embedded and daemon mode, while preserving the effective search type after runtime fallback.delete_by_namenow returns the same empty-result payload across backends when nothing matches, whileremove_documentpreservesNOT_FOUNDsemantics for strict hash deletes.update_documentnow returns a stable JSON shape in both embedded and daemon mode, including realupdatesApplied,tagsAdded, andtagsRemovedcounters from the daemon path.- Embedded graph query now works for corpus-backed mobile stores, but backend parity still needs review for edge cases and deletion/cleanup behavior.
yams_mobile_get_vector_statusstill carries legacy naming and a deprecatedwarmuprequest field, but the payload is now corpus-shaped andwarmupis explicitly ignored.- The documentation previously implied demo apps and ABI automation that are not present in this checkout.
Compatibility Strategy¶
- ABI version encoded in
yams_mobile_version_info(major/minor/patch) and mirrored in the header macrosYAMS_MOBILE_API_VERSION_{MAJOR,MINOR,PATCH}. - Every request struct now embeds a
struct_size/versionheader so older clients continue to function when fields are appended. Callers should initialize structs via theyams_mobile_context_config_default()/yams_mobile_request_header_default()helpers before setting additional fields. - Breaking changes must bump
YAMS_MOBILE_API_VERSION_MAJORand ship a parallel symbol surface (yams_mobile_v2_*) while preserving the previous version for at least one minor release. - The current source of truth for compatibility is the versioned C header plus mobile ABI smoke
coverage. CI now verifies that the built shared library exports every
YAMS_MOBILE_APIsymbol declared in the versioned header.
Build & Distribution¶
- CI packaging and ABI verification live in
mobile-builds.md(in the yams-app repository). - The current CI artifact is a host-native shared library bundle for validation and downstream
integration work, not yet a shipped
.xcframeworkor.aar. - The intended layering is:
- this repo publishes the native corpus library plus headers
- platform wrappers package that library for iOS/Android
- the Flutter app/plugin consumes those packaged native artifacts
Fixtures & Test Corpora¶
tests/common/search_corpus_presets.hexposesmobileSearchCorpusSpec()which captures the curated mobile dataset (sync deltas, path sensitivity, semantic warm-up, case toggles). Use this in unit/integration tests to align with the demo apps and smoke suites.tests/mobile/mobile_abi_smoke_test.cppnow runs on Catch2, validates the round-trip ingest/list/search flow against the new corpus, covers daemonget_document.include_contentparity, verifies embedded graph query on a corpus-backed store, checks the corpus-status payload in both embedded and daemon modes, and verifies stablesearch_execute,list_documents,delete_by_name, andupdate_documentpayload shapes across embedded and daemon backends, plusremove_documentstatus parity for missing hashes.update_documentcoverage now also asserts real tag counter parity instead of shape-only presence checks. The current suite also retries the first daemon store call in smoke coverage to absorb daemon-startup transport flakiness seen only in full-suite execution.
Platform Wrappers¶
Reference Swift/Android/Flutter wrappers are planned, but they are not yet checked into this repo.
Until those wrappers land, libyams_mobile should be treated as the stable integration seam and the
wrapper layer should stay intentionally thin.
Developer Workflow¶
- Initialize the fixtures using
FixtureManager(see smoke test for a template) or reuse the packaged corpora in CI. - Link against
yams_mobilefrom the host platform wrapper. - Validate corpus flows first: store, list, search, get, update, delete, metadata, and graph.
- Keep app-owned LLM concerns outside the bindings layer.