Skip to main content

Developer Guide

This guide provides everything you need to know about developing Osaurus, from building the project to contributing code.

πŸ—οΈ Architecture Overview​

Osaurus is built with a clean, modular architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ SwiftUI App │────▢│ Menu Bar UI β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ ServerController│────▢│ SwiftNIO HTTP β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ β”‚
β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Model Manager β”‚ β”‚ API Handler β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ MLX Service β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ Project Structure​

osaurus/
β”œβ”€β”€ Core/ # App lifecycle
β”‚ β”œβ”€β”€ AppDelegate.swift # macOS app delegate
β”‚ └── osaurusApp.swift # SwiftUI app entry point
β”‚
β”œβ”€β”€ Controllers/ # Business logic controllers
β”‚ β”œβ”€β”€ ServerController.swift # HTTP server lifecycle management
β”‚ β”œβ”€β”€ ModelManager.swift # Model discovery & downloads
β”‚ └── HotKeyManager.swift # Global hotkey registration
β”‚
β”œβ”€β”€ Models/ # Data models
β”‚ β”œβ”€β”€ InternalMessage.swift # Internal message types
β”‚ β”œβ”€β”€ MLXModel.swift # MLX model representation
β”‚ β”œβ”€β”€ OpenAIAPI.swift # OpenAI-compatible DTOs
β”‚ β”œβ”€β”€ ResponseWriters.swift # SSE and NDJSON writers
β”‚ β”œβ”€β”€ ServerConfiguration.swift # Server config model
β”‚ β”œβ”€β”€ ChatConfiguration.swift # Chat config model
β”‚ └── ServerHealth.swift # Health check model
β”‚
β”œβ”€β”€ Networking/ # Network layer
β”‚ β”œβ”€β”€ HTTPHandler.swift # HTTP request handling
β”‚ β”œβ”€β”€ Router.swift # URL routing with normalization
β”‚ └── AsyncHTTPHandler.swift # Async request processing
β”‚
β”œβ”€β”€ Services/ # Core services
β”‚ β”œβ”€β”€ DirectoryPickerService.swift # File system access
β”‚ β”œβ”€β”€ FoundationModelService.swift # Apple Intelligence integration
β”‚ β”œβ”€β”€ HuggingFaceService.swift # Model repository access
β”‚ β”œβ”€β”€ LoginItemService.swift # Auto-start functionality
β”‚ β”œβ”€β”€ MLXService.swift # MLX inference engine
β”‚ β”œβ”€β”€ ModelService.swift # Model management
β”‚ β”œβ”€β”€ PromptBuilder.swift # Chat template formatting
β”‚ β”œβ”€β”€ SearchService.swift # Model search
β”‚ β”œβ”€β”€ SharedConfigurationService.swift # Inter-app communication
β”‚ β”œβ”€β”€ SystemMonitorService.swift # CPU/RAM monitoring
β”‚ └── UpdaterService.swift # App updates
β”‚
β”œβ”€β”€ Theme/ # UI theming
β”‚ └── Theme.swift # Colors, fonts, styling
β”‚
β”œβ”€β”€ Views/ # SwiftUI views
β”‚ β”œβ”€β”€ Components/ # Reusable UI components
β”‚ β”œβ”€β”€ ContentView.swift # Main app view
β”‚ β”œβ”€β”€ ModelDownloadView.swift # Model browser
β”‚ β”œβ”€β”€ ChatView.swift # Chat interface
β”‚ └── SettingsView.swift # Configuration UI
β”‚
β”œβ”€β”€ Resources/ # Assets and resources
β”‚ β”œβ”€β”€ Assets.xcassets/ # Images and colors
β”‚ └── Info.plist # App metadata
β”‚
└── CLI/ # Command-line interface
└── main.swift # CLI entry point

πŸ› οΈ Development Setup​

Prerequisites​

  • macOS 15.5+ on Apple Silicon
  • Xcode 16.4+ with Command Line Tools
  • Swift 6.0+
  • Git

Clone and Build​

# Clone the repository
git clone https://github.com/dinoki-ai/osaurus.git
cd osaurus

# Open in Xcode
open osaurus.xcodeproj

# Or build from command line
xcodebuild -scheme osaurus -configuration Debug

Running in Development​

  1. In Xcode:

    • Select the osaurus scheme
    • Choose your Mac as the run destination
    • Press ⌘R to build and run
  2. Debug Console:

    • View logs in Xcode's console
    • Set breakpoints for debugging
    • Use lldb commands for inspection
  3. SwiftUI Previews:

    • Available for most views
    • Press ⌘βŒ₯P to refresh previews

πŸ”§ Key Components​

ServerController​

Manages the HTTP server lifecycle:

class ServerController: ObservableObject {
@Published var isRunning = false
@Published var port = 1337
@Published var isExposed = false

func start() async throws {
// Initialize SwiftNIO event loop
// Bind to configured address
// Start accepting connections
}

func stop() async {
// Gracefully shutdown server
// Clean up resources
}
}

MLXService​

Handles model loading and inference:

class MLXService {
private var loadedModel: MLXModel?
private var sessionCache: [String: InferenceSession] = [:]

func loadModel(_ name: String) async throws -> MLXModel {
// Check cache first
// Load model from disk
// Initialize tokenizer
// Warm up model
}

func generate(
prompt: String,
maxTokens: Int,
temperature: Float
) -> AsyncStream<String> {
// Tokenize input
// Run inference
// Stream tokens
// Handle stop sequences
}
}

Router​

Handles API path normalization:

struct Router {
static func normalize(_ path: String) -> String {
// Remove common prefixes (/v1, /api, etc.)
// Standardize paths
// Return canonical route
}

static func route(_ request: HTTPRequest) -> Handler? {
let path = normalize(request.uri)
switch path {
case "/models": return ModelsHandler()
case "/chat/completions": return ChatHandler()
// ... more routes
default: return nil
}
}
}

πŸ§ͺ Testing​

Unit Tests​

# Run all tests
xcodebuild test -scheme osaurus

# Run specific test
xcodebuild test -scheme osaurus -only-testing:osaurusTests/MLXServiceTests

Integration Tests​

# test_integration.py
import pytest
import requests

def test_chat_completion():
response = requests.post(
"http://localhost:1337/v1/chat/completions",
json={
"model": "llama-3.2-3b-instruct-4bit",
"messages": [{"role": "user", "content": "Hello"}]
}
)
assert response.status_code == 200
assert "choices" in response.json()

Performance Testing​

# Run benchmark suite
./scripts/run_bench.sh

# Profile with Instruments
xcrun xctrace record --template "Time Profiler" --launch osaurus

🎨 UI Development​

SwiftUI Best Practices​

// Use @StateObject for view models
struct ChatView: View {
@StateObject private var viewModel = ChatViewModel()

var body: some View {
// Use ViewBuilder for complex layouts
// Prefer computed properties
// Extract reusable components
}
}

// Create reusable components
struct MessageBubble: View {
let message: ChatMessage

var body: some View {
Text(message.content)
.padding()
.background(bubbleColor)
.cornerRadius(12)
}

private var bubbleColor: Color {
message.role == .user ? .blue : .gray
}
}

Theme System​

extension Color {
static let osaurusPrimary = Color("AccentColor")
static let osaurusBackground = Color("BackgroundColor")
}

extension Font {
static let osaurusTitle = Font.system(.largeTitle, design: .rounded)
static let osaurusBody = Font.system(.body)
}

πŸ”Œ Adding New Features​

1. New Model Support​

// 1. Add model definition
struct NewModel: MLXModel {
let architecture = "new_arch"
let tokenizer = "new_tokenizer"
}

// 2. Update model registry
ModelRegistry.register(NewModel.self, for: "new_arch")

// 3. Add to UI
ModelManager.suggestedModels.append(
SuggestedModel(name: "New Model", repo: "org/model")
)

2. New API Endpoint​

// 1. Create handler
class CustomHandler: HTTPHandler {
func handle(_ request: HTTPRequest) async -> HTTPResponse {
// Process request
// Return response
}
}

// 2. Add route
Router.addRoute("/custom", handler: CustomHandler())

// 3. Document in OpenAPI

3. New Settings​

// 1. Add to configuration model
struct ServerConfiguration {
var newSetting: Bool = false
}

// 2. Add UI control
Toggle("New Feature", isOn: $config.newSetting)

// 3. Persist to UserDefaults
@AppStorage("newSetting") var newSetting = false

πŸ“¦ Dependencies​

Core Dependencies​

  • SwiftNIO - High-performance HTTP server
  • MLX-Swift - ML framework for Apple Silicon
  • MLXLLM - LLM-specific MLX extensions

Development Dependencies​

  • SwiftLint - Code linting
  • XCTest - Unit testing
  • Instruments - Performance profiling

Package Management​

// Package.swift
dependencies: [
.package(url: "https://github.com/ml-explore/mlx-swift", from: "0.10.0"),
.package(url: "https://github.com/apple/swift-nio.git", from: "2.50.0"),
]

πŸ› Debugging​

Common Issues​

Model Loading Failures

// Check model path
print(modelPath.path)

// Verify files exist
let requiredFiles = ["config.json", "model.safetensors"]
for file in requiredFiles {
assert(FileManager.default.fileExists(atPath: modelPath.appendingPathComponent(file).path))
}

Memory Issues

// Monitor memory usage
let memory = ProcessInfo.processInfo.physicalMemory
print("Available memory: \(memory / 1024 / 1024 / 1024)GB")

// Force model unload
MLXService.shared.unloadModel()

Network Errors

// Enable verbose logging
HTTPHandler.logLevel = .trace

// Check port binding
netstat -an | grep 1337

Debug Helpers​

// Add debug commands
#if DEBUG
extension ChatView {
func debugMenu() -> some View {
Menu("Debug") {
Button("Clear Cache") { MLXService.shared.clearCache() }
Button("Print Stats") { printDebugStats() }
Button("Force Crash") { fatalError("Debug crash") }
}
}
}
#endif

πŸš€ Performance Optimization​

Model Loading​

  • Cache loaded models in memory
  • Implement lazy loading
  • Use memory mapping for weights

Inference​

  • Batch similar requests
  • Implement request queuing
  • Use streaming for long outputs

UI Responsiveness​

  • Offload heavy work to background queues
  • Use SwiftUI's task modifier
  • Implement progressive loading

🀝 Contributing​

Code Style​

Follow Swift style guide:

  • Use descriptive names
  • Document public APIs
  • Keep functions focused
  • Prefer immutability

Pull Request Process​

  1. Fork and create feature branch
  2. Write tests for new features
  3. Update documentation
  4. Run SwiftLint
  5. Submit PR with description

Commit Messages​

feat: Add support for new model architecture
fix: Resolve memory leak in streaming responses
docs: Update API documentation
test: Add integration tests for tool calling
refactor: Simplify router implementation

πŸ“š Resources​

Documentation​

Tools​

Community​

πŸ” Security​

Best Practices​

  • Validate all inputs
  • Sanitize file paths
  • Use secure random for IDs
  • Implement rate limiting
  • Log security events

Reporting Issues​

See SECURITY.md for reporting vulnerabilities.


Ready to contribute?
Check out good first issues to get started!