name: wax description: Comprehensive guidance for the Wax on-device memory/RAG framework. Use when integrating MemoryOrchestrator, VideoRAGOrchestrator, Wax/WaxSession, embedding providers, hybrid search, maintenance, or when evaluating Wax constraints like offline-only, single-file .wax persistence and deterministic retrieval.
Wax
Overview
Use this skill to design and implement correct Wax-based on-device RAG flows in Swift 6.2, emphasizing deterministic retrieval, single-file persistence, and safe concurrency.
Choose The API Surface
- Prefer
MemoryOrchestratorfor text memory and retrieval. - Use
VideoRAGOrchestratorfor on-device video RAG (keyframes + transcripts). - Use
WaxandWaxSessionfor lower-level indexing, unified search, or structured memory. - Import
Waxto get re-exported core/search/vector APIs.
Core Workflow
- Choose a
.waxstore URL. - Configure
OrchestratorConfig(disable vector search if no embedder). - Provide an
EmbeddingProviderwhen vector search is enabled. - Call
remember(...)to ingest andrecall(...)to buildRAGContext. - Call
flush()orclose()to persist.
Safety & Constraints
- Keep Wax offline-only; no network calls are made. See
references/constraints.md. - Treat the
.waxfile as the single source of truth (data + indexes + WAL). - Provide an embedder when vector search is enabled and no vector index exists.
- Use
QueryEmbeddingPolicydeliberately;.alwaysthrows if vector search is disabled or no embedder is configured. - For Video RAG, supply transcripts; Wax does not transcribe in v1.
- Ensure multimodal embeddings are normalized when using Metal-backed vector search in Video RAG.
Performance & Determinism Tips
- Use
WaxPrewarm.tokenizer()to reduce first-query latency. - If MiniLM is available, use
MemoryOrchestrator.openMiniLM(...)orWaxPrewarm.miniLM(...)to warm embeddings. - Prefer
.ifAvailablequery embeddings unless you require hard failures.
Examples
import Foundation
import Wax
func demoTextOnly() async throws {
let url = FileManager.default.temporaryDirectory
.appendingPathComponent("wax-memory")
.appendingPathExtension("wax")
var config = OrchestratorConfig.default
config.enableVectorSearch = false
let memory = try await MemoryOrchestrator(at: url, config: config)
try await memory.remember("User: prefers Swift over Java.")
let ctx = try await memory.recall(query: "preferences")
_ = ctx.items
try await memory.close()
}
import Foundation
import Wax
actor MyEmbedder: EmbeddingProvider {
let dimensions = 384
let normalize = true
let identity: EmbeddingIdentity? = .init(
provider: "Local",
model: "v1",
dimensions: 384,
normalized: true
)
func embed(_ text: String) async throws -> [Float] {
[Float](repeating: 0.0, count: dimensions)
}
}
func demoVector() async throws {
let url = FileManager.default.temporaryDirectory
.appendingPathComponent("wax-vector")
.appendingPathExtension("wax")
var config = OrchestratorConfig.default
config.enableVectorSearch = true
let memory = try await MemoryOrchestrator(at: url, config: config, embedder: MyEmbedder())
try await memory.remember("Vector search enabled.")
let ctx = try await memory.recall(query: "vector")
_ = ctx.totalTokens
try await memory.flush()
try await memory.close()
}
import Foundation
import Wax
import CoreGraphics
struct MyVideoEmbedder: MultimodalEmbeddingProvider {
let dimensions = 768
let normalize = true
let identity: EmbeddingIdentity? = .init(
provider: "Local",
model: "clip-v1",
dimensions: 768,
normalized: true
)
func embed(text: String) async throws -> [Float] { [Float](repeating: 0.0, count: dimensions) }
func embed(image: CGImage) async throws -> [Float] { [Float](repeating: 0.0, count: dimensions) }
}
struct MyTranscriptProvider: VideoTranscriptProvider {
func transcript(for request: VideoTranscriptRequest) async throws -> [VideoTranscriptChunk] {
[]
}
}
func demoVideo() async throws {
let storeURL = FileManager.default.temporaryDirectory
.appendingPathComponent("wax-video")
.appendingPathExtension("wax")
let rag = try await VideoRAGOrchestrator(
storeURL: storeURL,
embedder: MyVideoEmbedder(),
transcriptProvider: MyTranscriptProvider()
)
try await rag.ingest(files: [
VideoFile(id: "clip-1", url: URL(fileURLWithPath: "/path/to/clip.mp4"))
])
let ctx = try await rag.recall(.init(text: "find the opening scene"))
_ = ctx.items
try await rag.flush()
}
Glossary
MemoryOrchestrator: High-level API for ingesting text and buildingRAGContext.RAGContext: Deterministic retrieval output with items and total token count.EmbeddingProvider: Supplies text embeddings for vector search.VideoRAGOrchestrator: On-device video ingestion and recall over keyframes and transcripts.VideoQuery: Video recall parameters (text, time range, IDs, budgets).
References
references/public-api.mdreferences/constraints.md
Templates
templates/init-store-embedder.mdtemplates/remember-recall-lifecycle.mdtemplates/hybrid-search.mdtemplates/maintenance.mdtemplates/video-rag-transcripts.md