Askimo Desktop Architecture Guide
Overview
Section titled “Overview”The Askimo Desktop application is a native desktop client built with Jetpack Compose for Desktop. It provides a rich, responsive user interface for interacting with AI assistants across multiple providers.
Key Technologies
Section titled “Key Technologies”- UI Framework: Jetpack Compose for Desktop
- Language: Kotlin
- Architecture Pattern: MVVM (Model-View-ViewModel)
- Dependency Injection: Koin
- Concurrency: Kotlin Coroutines
- Persistence: Shared with CLI module (SQLite via Exposed)
Architecture Overview
Section titled “Architecture Overview”The desktop application follows a layered architecture with clear separation of concerns:
graph TD
A[UI Layer
Jetpack Compose Views & Components]
B[ViewModel Layer
State Management & UI Logic]
C[Service Layer
Business Logic & Coordination]
D[Core Layer
Shared Module: Providers, Session, Repository]
A --> B
B --> C
C --> D
style A fill:#e1f5ff,stroke:#0288d1,stroke-width:2px
style B fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
style C fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
style D fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
Design Principles
Section titled “Design Principles”- Separation of Concerns: Each layer has a specific responsibility
- Unidirectional Data Flow: Data flows down, events flow up
- Reactive Programming: UI automatically updates when state changes
- Single Source of Truth: State is owned by ViewModels
- Dependency Injection: Loose coupling between components
Module Organization
Section titled “Module Organization”The desktop module is organized into the following key packages:
desktop/├── Main.kt # Application entry point├── viewmodel/ # ViewModels (UI state management)├── service/ # Business logic services├── ui/ # UI components│ ├── views/ # Main application views│ ├── components/ # Reusable UI components│ └── theme/ # Theming and styling├── model/ # UI data models├── di/ # Dependency injection configuration├── i18n/ # Internationalization├── keymap/ # Keyboard shortcuts└── util/ # Utility classesPackage Responsibilities
Section titled “Package Responsibilities”| Package | Purpose |
|---|---|
viewmodel/ | Manages UI state and handles user actions |
service/ | Contains business logic and coordinates operations |
ui/views/ | Main application screens (Chat, Sessions, Settings) |
ui/components/ | Reusable UI elements (dialogs, message bubbles, etc.) |
ui/theme/ | Color schemes, typography, and theme management |
model/ | Data classes for UI representation |
di/ | Koin dependency injection modules |
i18n/ | Multi-language support |
keymap/ | Keyboard shortcut management |
util/ | Helper functions and utilities |
Architectural Layers
Section titled “Architectural Layers”1. UI Layer (Jetpack Compose)
Section titled “1. UI Layer (Jetpack Compose)”The presentation layer built with Compose for Desktop. Responsible for rendering the user interface and capturing user interactions.
Main Views:
- ChatView: Primary chat interface
- SessionsView: Session list and management
- SettingsView: Application configuration
- AboutView: Application information
Reusable Components:
- Message bubbles with markdown and code highlighting
- File attachment handling
- Dialogs and modals
- Tooltips and dropdowns
- Theme-aware styling
2. ViewModel Layer (MVVM Pattern)
Section titled “2. ViewModel Layer (MVVM Pattern)”Manages UI state and handles user actions. Acts as the bridge between UI and business logic.
ViewModels:
- ChatViewModel: Chat state, messages, streaming responses
- SessionsViewModel: Session list, operations (star, delete, rename)
- SettingsViewModel: Configuration and preferences
Responsibilities:
- Maintain UI state
- Handle user actions
- Coordinate with services
- Manage lifecycle and cleanup
3. Service Layer
Section titled “3. Service Layer”Contains business logic and coordinates operations between ViewModels and the Core layer.
Key Services:
- ChatService: Chat operations and session management
- StreamingService: AI response streaming coordination
- ThemePreferences: User preference persistence
Responsibilities:
- Encapsulate business rules
- Provide clean APIs to ViewModels
- Handle concurrent operations
- Manage resource lifecycle
4. Core Layer (Shared Module)
Section titled “4. Core Layer (Shared Module)”Shared functionality used by both CLI and Desktop applications. Provides core AI chat capabilities.
Components:
- Session: Chat session management
- Providers: AI provider integrations (OpenAI, Anthropic, etc.)
- Repository: Data persistence layer
- Models: Domain models
5. Cross-Cutting Concerns
Section titled “5. Cross-Cutting Concerns”Dependency Injection (Koin):
- Manages component lifecycle
- Provides loose coupling
- Supports testability
Internationalization:
- Multi-language support (English, Japanese, Vietnamese)
- Localized UI strings
- Parameter substitution
Platform Utilities:
- OS detection (macOS, Windows, Linux)
- Keyboard shortcut management
- Platform-specific behaviors
Data Flow
Section titled “Data Flow”The application follows a unidirectional data flow pattern:
graph TD
A[User Input] --> B[ViewModel]
B --> C[Service]
C --> D[Core]
B -->|State Update| E[UI Update]
style A fill:#e1f5ff,stroke:#0288d1,stroke-width:2px
style B fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
style C fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
style D fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style E fill:#fce4ec,stroke:#c2185b,stroke-width:2px
Key Flows
Section titled “Key Flows”Sending a Message:
- User types message in ChatView
- ChatViewModel processes the input
- ChatService coordinates with Core layer
- AI provider streams the response
- ViewModel updates state reactively
- UI automatically recomposes to show response
Loading a Session:
- User selects session from list
- ViewModel requests session data
- Repository loads from database
- ViewModel updates message list
- UI renders the chat history
Key Design Patterns
Section titled “Key Design Patterns”1. MVVM (Model-View-ViewModel)
Section titled “1. MVVM (Model-View-ViewModel)”The application uses the MVVM pattern to separate concerns:
- View (UI): Jetpack Compose components that display data
- ViewModel: Manages UI state and handles user actions
- Model: Data layer (repositories, services, domain models)
2. Reactive State Management
Section titled “2. Reactive State Management”State changes automatically trigger UI updates:
- ViewModels expose state using Compose’s
mutableStateOf - UI observes state changes and recomposes automatically
- Kotlin Flows handle streaming data
3. Dependency Injection
Section titled “3. Dependency Injection”Koin provides loose coupling between components:
- Dependencies are injected via constructors
- Lifecycle management is handled automatically
- Easy to swap implementations for testing
4. Repository Pattern
Section titled “4. Repository Pattern”Data access is abstracted through repositories:
- ViewModels don’t directly access the database
- Repositories provide a clean API for data operations
- Easy to add caching or remote data sources
Platform Support
Section titled “Platform Support”The desktop application runs on multiple platforms with platform-specific adaptations:
Supported Platforms
Section titled “Supported Platforms”- macOS: Full native integration with system menu and keyboard shortcuts
- Windows: Native look and feel with Windows-specific shortcuts
- Linux: Cross-desktop environment support
Platform Utilities
Section titled “Platform Utilities”OS Detection:
- Centralized detection of the current operating system
- Platform-specific keyboard shortcuts (Command vs. Ctrl)
- Adaptive UI elements based on platform conventions
Keyboard Shortcuts:
- Platform-aware shortcut management
- Consistent shortcuts across platforms where possible
- Platform-specific shortcuts where appropriate (e.g., ⌘+Q vs. Alt+F4)
Development Guidelines
Section titled “Development Guidelines”Code Organization
Section titled “Code Organization”- Separation of Concerns: Keep UI, business logic, and data layers separate
- Single Responsibility: Each class should have one clear purpose
- Dependency Injection: Use Koin for managing dependencies
- Reactive State: Leverage Kotlin Flows and Compose state management
State Management
Section titled “State Management”- ViewModels own and manage UI state
- State is immutable and exposed as read-only properties
- UI reacts automatically to state changes
- State is scoped to ViewModel lifecycle
Asynchronous Operations
Section titled “Asynchronous Operations”- Use Kotlin Coroutines for all async operations
- Scope coroutines to ViewModel lifecycle
- Handle cancellation gracefully
- Use appropriate dispatchers (IO, Default, Main)
UI Development
Section titled “UI Development”- Keep Composables small and focused
- Extract reusable components
- Use theming system for consistent styling
- Never put business logic in Composables
Contributing
Section titled “Contributing”When contributing to the desktop module, please:
- Follow the MVVM architecture pattern
- Keep layers properly separated
- Write tests for new features
- Update documentation as needed
- Follow Kotlin coding conventions