A sleek, modern AI chat assistant for every platform. Private, powerful, and model-flexible.
- Features
- Quick Start
- Architecture
- Model Integration
- Configuration
- Building for Each Platform
- Roadmap
- Contributing
- License
- Runs natively on Web, macOS, Windows, Linux, iOS and Android
- Single codebase maintained in Flutter 3.22 and Dart 3
- Model picker dropdown with presets for:
- OpenAI (GPT‑3.5 Turbo, GPT‑4o)
- Anthropic Claude 3
- Google Gemini 1.5
- Meta Llama 3 (OpenAI compatible endpoint)
- Local GGUF models served over llama.cpp or Ollama
- Streaming markdown output with syntax highlighted code blocks
- Conversation memory with local searchable history
- Offline first: data stays on device unless cloud sync is enabled
- Function calling and JSON mode for tool invocation
- Theming (light, dark, system) and 20+ accent colours
- Localisation with Flutter Intl
- Accessibility tested with TalkBack and VoiceOver
- Flutter stable channel (3.22 or newer)
- Dart SDK (included with Flutter)
- An API key for at least one supported provider
- Optional: llama.cpp server or Ollama for local models
git clone https://github.com/yourorg/elloAI.git
cd elloAI
flutter pub get
# Start in the browser
flutter run -d chrome
# Run on Android emulator
flutter emulators --launch android
flutter run -d emulator-5554Create a .env file at the project root:
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=...
GEMINI_API_KEY=...
LLAMA_ENDPOINT=http://localhost:11434Keys can also be added through the in-app settings panel.
If no OPENAI_API_KEY is provided, the app uses a built-in mock model for local testing.
- UI: Flutter Material 3 with Riverpod for state management
- Networking: Dart
httppackage with Server Sent Events - LLM Abstraction:
lib/src/llm_client/defines a commonChatClientinterface per provider - Persistence:
isardatabase for local storage, optional Firebase sync layer - Background tasks:
flutter_workmanagerplugin
A full diagram lives in /docs/architecture.drawio.
| Platform | Command | Artifact |
|---|---|---|
| Web | flutter build web --release |
build/web |
| Android | flutter build apk --release |
build/app/outputs/flutter-apk/app-release.apk |
| iOS | flutter build ipa --release |
Xcode archive |
| Windows | flutter build windows --release |
build/windows/runner/Release |
| macOS | flutter build macos --release |
.app bundle |
| Linux | flutter build linux --release |
build/linux/x64/release/bundle |
CI workflows build and upload signed artefacts on each push to main.
All providers implement:
Stream<ChatChunk> chat({
required List<Message> messages,
ModelConfig config,
})To add a new model:
- Create a class in
lib/src/llm_client/ - Implement
ChatClient - Register it in
providers/llm_providers.dart - Expose it in
ui/settings/model_picker.dart
ello.AI supports connecting to a gRPC server for chat functionality. The app includes:
- Proto definitions in
/protos/chat.proto - Generated Dart client code in
lib/src/generated/ - A gRPC client service in
lib/src/services/chat_service_client.dart
Initialize the connection using the grpcConnectionProvider:
final config = GrpcConnectionConfig(
host: 'localhost', // Change to your server's host
port: 50051, // Change to your server's port
secure: false, // Set to true for TLS
);
// Initialize the connection
await ref.read(grpcConnectionProvider(config).future);The app includes gRPC-Web support for better compatibility with services like Cloud Run:
- For Cloud Run and other similar services, gRPC-Web is automatically enabled
- You can toggle between standard gRPC and gRPC-Web in the debug settings
The client automatically detects Cloud Run services (domains ending with run.app) and defaults to gRPC-Web mode with secure connections.
In debug mode, a bug icon appears in the app bar that opens debug settings:
- Toggle between mock and real gRPC clients
- Switch between standard gRPC and gRPC-Web
- Edit gRPC server connection details (host, port, secure mode)
- Test connection to verify your settings
- Reset to production or local development settings
- Monitor connection failures and toggle auto-fallback to mock mode
The debug UI is only available in debug builds and will not appear in release builds.
Use the chatStreamProvider to stream responses:
// Assume messages is a List<YourMessageType>
ref.read(chatStreamProvider(messages)).when(
data: (response) {
// Handle each chunk from the stream
print('Received: ${response.content}');
// Check if the stream is complete
if (response.isDone) {
print('Stream completed');
}
},
loading: () {
// Stream is being processed
},
error: (error, stackTrace) {
print('Error: $error');
},
);A sample Go server is included in the /server directory:
cd server
go run main.goThe server listens on port 50051 by default and provides an echo service for testing.
- Voice input powered by OpenAI Whisper
- Image understanding with Gemini Vision
- Calendar and email plugins
- In-app prompt engineering playground
- Self-hosted Rust backend
- Fork and create a feature branch
- Write unit and widget tests
- Run
dart formatandflutter analyze - Open a pull request against
main
This project uses GitHub Actions for continuous integration. Every pull request triggers:
- Flutter Checks: Linting, formatting, and tests
- Go Server Checks: Formatting, vetting, and tests
- Build Verification: Ensures all platforms compile
- Security Scanning: Vulnerability detection
Run the local validation script before pushing:
./scripts/pre-push-check.shThis script runs the same checks as the CI pipeline locally, saving time and preventing failed builds.
The main branch is protected and requires:
- All status checks to pass
- At least one approval
- Conversation resolution
Branch protection is configured and enforced automatically via GitHub settings.
MIT. See LICENSE for the full text.