OpenChat is an iOS role-playing chat client for OpenAI-compatible APIs. It is built for character-card based conversations, world-book recall, long-running role-play context, and local-first experimentation with small or self-hosted models.
The app is written in SwiftUI and uses native Swift Concurrency, SQLite via GRDB, URLSession streaming, and a small CoreML embedding model for semantic memory and world-book retrieval.
- OpenAI-compatible Chat Completions and Responses API modes
- Multiple API endpoints and per-conversation model parameters
- Character cards with persona, scenario, example dialog, import, and export support
- World books with keyword and semantic recall
- Streaming chat UI with markdown rendering and visible reasoning/thinking support
- Persistent conversation history in SQLite
- Context management with truncation and checkpoint-style compression
- Cross-conversation character memory with vector retrieval
- Stage mode for multi-character scenes, speaker metadata, and user-controlled response order
- Background source tooling for memory, world-book, and conversation-state context packets
- macOS with Xcode 17 or newer
- iOS 17 or newer
- Swift 6 toolchain from Xcode
- An OpenAI-compatible API endpoint
The project is an Xcode project, not a Swift Package. Use xcodebuild or open OpenChat.xcodeproj in Xcode.
Clone the repository:
git clone git@github.com:logic10492/openchat.git
cd openchatOpenChat/Resources/Models is intentionally not tracked and is not a Git submodule. It is ignored because the CoreML model assets are large generated files.
Semantic memory and semantic world-book recall expect these local files when enabled:
OpenChat/Resources/Models/
|-- MultilingualE5Small.mlpackage
`-- tokenizer.json
The model used by the current implementation is a CoreML conversion of intfloat/multilingual-e5-small:
- CoreML conversion reference: https://huggingface.co/fanstudioapps/multilingual-e5-small-coreml-embedder-256-512
- Original upstream model: https://huggingface.co/intfloat/multilingual-e5-small
Place the model package and tokenizer under OpenChat/Resources/Models/ before running embedding-backed tests or using semantic retrieval locally.
Open the project:
open OpenChat.xcodeprojOr build from the command line:
xcodebuild \
-project OpenChat.xcodeproj \
-scheme OpenChat \
-destination 'platform=iOS Simulator,name=iPhone 17' \
buildThe exact simulator name depends on your installed Xcode runtime. Use this command to list available devices:
xcrun simctl list devices availableRun the unit test target:
xcodebuild test \
-project OpenChat.xcodeproj \
-scheme OpenChat \
-destination 'platform=iOS Simulator,name=iPhone 17' \
-only-testing:OpenChatTests \
-skip-testing:OpenChatUITestsUI tests are under OpenChatUITests and can be run separately from Xcode or with xcodebuild when a suitable simulator is available.
OpenChat/
|-- App/ App entry, dependency container, global app state
|-- Core/ Database, networking, prompt engine, context, memory, stage, background
|-- Features/ Chat, character cards, world books, conversations, settings, stage UI
|-- Resources/ Assets, localization, optional local models
`-- Shared/ Shared SwiftUI components and utilities
OpenChatTests/ Swift Testing unit tests
OpenChatUITests/ UI tests
arch/ Architecture notes and implementation evidence
scripts/ Project generation and maintenance scripts
The architecture follows a one-way dependency rule:
App -> Features -> Core -> Shared
Features should not directly depend on each other. Cross-feature coordination should live in the App layer or in Core services.
Configure API endpoints inside the app settings. OpenChat stores endpoint metadata locally and keeps API keys outside the main SQLite database through the app's key storage layer.
Supported provider shapes include:
- OpenAI-compatible Chat Completions
- OpenAI Responses-style requests
- DeepSeek-compatible reasoning content and thinking-parameter handling
- Local servers that expose compatible
/chat/completionsAPIs
The arch/ folder contains implementation-oriented architecture docs:
arch/index.md- project overviewarch/source-tree.md- source layoutarch/data-model.md- SQLite tables and recordsarch/modules/chat.md- chat runtime and UIarch/modules/prompt-assembly.md- prompt assembly flowarch/modules/context-manager.md- truncation and compressionarch/modules/memory/index.md- character memory systemarch/modules/stage/index.md- multi-character stage modearch/modules/background/index.md- background context sources and workersarch/modules/settings/index.md- settings and endpoint management
- Keep SwiftUI view models on
@Observable; do not introduce Combine-basedObservableObjectfor new app view models. - Use Swift Concurrency (
async/await,AsyncSequence) for asynchronous work. - Keep database changes append-only through GRDB migrations.
- Do not edit signing settings casually. Signing values are generated by
scripts/generate_xcodeproj.rb. - Keep architecture docs, source, and tests in sync when changing runtime behavior.
No license has been selected yet.