Open SourceAiPersona
Swift Package · Swift

Memory that says 'I remember' and means it.

AiPersona is an embeddable, on-device long-term memory engine for AI chat apps on Apple platforms — a bi-temporal knowledge graph, hybrid BM25 + embedding retrieval, and LLM-driven fact extraction and correction, reshaped from synapse-cortex's cognitive core for a single-user, embedded target instead of a multi-tenant server.

$.package(url: "https://github.com/NerdSnipe-Inc/AiPersona.git", from: "1.0.0")
SwiftData
Store
Multi
Providers
On-device
Default
What's inside

Bi-temporal fact graph

MemoryGraphStore holds EntityNode, EpisodicNode, and FactEdge SwiftData models. Corrections invalidate a fact by setting invalidAt — facts are never deleted, so the full history is always reconstructable.

Deterministic entity resolution

upsertEntity tries an exact case-insensitive match first, then falls back to token-subset and initials matching. Embedding similarity is deliberately not used for names — word-vector embeddings have no real coverage for proper nouns.

Corrections that find the right fact

invalidateFacts matches a correction to the fact it's actually about by cosine similarity, regardless of predicate string wording, and returns whether anything was actually invalidated — so a caller can tell the user when a correction didn't land.

Background ingestion, serialized safely

IngestionActor is a Swift actor, so concurrent enqueue calls are naturally serialized — which also protects against extraction-provider rate limits with no extra concurrency-limiting code. Extraction failures are logged and swallowed; ingestion never surfaces as a user-facing error.

Hybrid retrieval, two layers

RetrievalService mirrors synapse-cortex's hydration + per-turn split: a cached, budgeted session compilation plus a per-turn BM25 + embedding hybrid search with reciprocal rank fusion.

Multi-provider by design

Fact extraction and chat generation are independently selectable between on-device MLX, Gemini, OpenAI, and Anthropic — plus optional Notion export/import, knowledge-graph visualization export, and Gemini context caching.

Add to your Package.swift
Package
$.package(url: "https://github.com/NerdSnipe-Inc/AiPersona.git", from: "1.0.0")
Target
$.target(name: "YourApp", dependencies: ["AiPersona"])

Depends on AIChatKit (AIChatCore, AIChatOpenAI, AIChatAnthropic) and AIChatKitMLX (AIChatMLX). Resolves from a sibling checkout if present, otherwise from GitHub — set SPI_PROCESSING or FORCE_REMOTE_PACKAGES to force remote resolution.

Scope

A headless library, not a chat server.

AiPersona stores and retrieves memory; it doesn't run a chat loop. It builds prompt fragments for a host app's own chat system to consume — no backend, no account system, and no user data sent anywhere unless the host app opts into an external LLM/embedding provider.

It's single-user by design: one local user per host app instance, unlike the multi-tenant FastAPI server (synapse-cortex) it's adapted from.

Frequently asked

Does this require a backend?

No. AiPersona is fully on-device by default, using SwiftData for storage and Apple's NLEmbedding for local embeddings. A backend is only involved if you configure an external LLM/embedding provider for extraction.

What's the relationship to synapse-cortex?

AiPersona is a from-scratch Swift Package reimplementation of synapse-cortex's cognitive core, reshaped for a single-user, embedded target instead of a multi-tenant FastAPI server. See source-compared.md in the repo for a feature-by-feature comparison.

Can memory be edited or deleted by the user?

Yes — the graph exposes activeFacts(), allFacts() (including invalidated history), and allEntities(), so a host app can build a browse/correct/delete UI on top of it.

Give your chat app real memory.

Add AiPersona alongside AIChatKit to give your chat app a local, bi-temporal memory graph — no backend required.