Skip to main content

Developer Guide

This guide covers everything you need to know about contributing to Osaurus, building from source, and extending the platform with plugins.

Why Contribute to Osaurus?

Osaurus is built with native Swift—not Python, not Electron, not wrapped web tech. This matters:

AspectPython/ElectronNative Swift
PerformanceInterpreter overhead, GC pausesCompiled, ARC memory management
Startup200ms+ for Python runtimeUnder 10ms binary load
Memory50MB+ baselineMinimal footprint
IntegrationBridging requiredNative macOS APIs

Contributing to Osaurus means building production-quality tools that developers actually want to use daily.

Getting Started

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.xcworkspace

# Build and run the "osaurus" scheme
# Press ⌘R or Product → Run

Project Structure

osaurus/
├── App/ # Main application
│ ├── Core/ # App lifecycle
│ ├── Controllers/ # Business logic
│ ├── Models/ # Data models
│ ├── Networking/ # HTTP layer
│ ├── Services/ # Core services
│ ├── Views/ # SwiftUI views
│ └── CLI/ # Command-line interface

├── Packages/ # Swift packages
│ ├── OsaurusCore/ # Shared core library
│ │ └── Tools/
│ │ └── PluginABI/ # C ABI for plugins
│ └── ...

├── osaurus.xcworkspace # Xcode workspace
└── Makefile # Build automation

Running in Development

  1. Select the osaurus scheme in Xcode
  2. Choose "My Mac" as the run destination
  3. Press ⌘R to build and run
  4. View logs in Xcode's console

Architecture Overview

┌─────────────────┐     ┌─────────────────┐
│ SwiftUI App │────▶│ Menu Bar UI │
└────────┬────────┘ └─────────────────┘


┌─────────────────┐ ┌─────────────────┐
│ ServerController│────▶│ SwiftNIO HTTP │
└────────┬────────┘ └────────┬────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Model Manager │ │ API Handler │
└────────┬────────┘ └────────┬────────┘
│ │
└───────┬───────────────┘

┌─────────────────────────────────────────┐
│ MLX Service │
│ (Inference, Token Streaming) │
└─────────────────────────────────────────┘


┌─────────────────────────────────────────┐
│ Plugin Manager │
│ (Tool Loading, MCP Protocol) │
└─────────────────────────────────────────┘

Contributing

Finding Issues

Start with issues labeled "good first issue":

Browse Good First Issues →

Pull Request Process

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Make your changes with tests
  4. Run SwiftLint: swiftlint
  5. Submit a PR with a clear description

Commit Messages

Follow conventional commits:

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

Code Style

  • Use descriptive names
  • Document public APIs
  • Keep functions focused and small
  • Prefer immutability (let over var)
  • Follow existing patterns in the codebase

Building Plugins

Osaurus has a powerful plugin system for extending AI agent capabilities. Plugins are native binaries that expose tools via the MCP protocol.

Quick Start

# Scaffold a new Swift plugin
osaurus tools create MyPlugin --language swift
cd MyPlugin

# Build
swift build -c release

# Install locally
osaurus tools install .

Plugin Architecture

Plugins use a C ABI for compatibility:

@_cdecl("osaurus_plugin_entry")
func osaurusPluginEntry() -> UnsafeMutableRawPointer {
// Return function table
}

See the Plugin Authoring Guide for complete documentation.

Why Native Plugins?

Python-based MCP tools (like those using uv) have significant overhead:

  • ~200ms startup for Python interpreter
  • Higher memory due to GC and runtime
  • GIL limitations for parallelism

Native Swift/Rust plugins:

  • Under 10ms load time
  • Minimal memory footprint
  • True parallelism

This matters when AI agents execute dozens of tool calls per session.

Testing

Unit Tests

# Run all tests
xcodebuild test -workspace osaurus.xcworkspace -scheme osaurus

# Run specific test
xcodebuild test -workspace osaurus.xcworkspace -scheme osaurus \
-only-testing:OsaurusTests/MLXServiceTests

Integration Tests

# test_integration.py
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

Key Components

MLXService

Handles model loading and inference:

class MLXService {
func loadModel(_ name: String) async throws -> MLXModel
func generate(prompt: String, maxTokens: Int) -> AsyncStream<String>
}

PluginManager

Manages tool plugins:

class PluginManager {
func loadPlugin(at path: URL) throws
func invoke(tool: String, arguments: [String: Any]) async throws -> Any
}

HTTPHandler

Processes API requests:

struct HTTPHandler: ChannelInboundHandler {
func channelRead(context: ChannelHandlerContext, data: NIOAny)
}

Debugging

Common Issues

Model loading fails:

// Check model path
print(modelPath.path)

// Verify required files
let required = ["config.json", "model.safetensors"]

Plugin won't load:

# Check code signature
codesign -v libMyPlugin.dylib

# Check for missing symbols
nm -g libMyPlugin.dylib | grep osaurus_plugin_entry

Memory issues:

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

Debug Logging

#if DEBUG
Logger.shared.level = .trace
#endif

Developer Tools

Osaurus includes built-in developer tools for debugging and monitoring your AI applications. Access them via the Management window (⌘⇧M).

Insights

The Insights panel provides real-time monitoring of all API activity:

Request Monitoring:

  • View all incoming API requests as they happen
  • See full request and response payloads
  • Filter by HTTP method (GET/POST)
  • Filter by source (Chat UI vs HTTP API)

Performance Stats:

  • Success rate percentage
  • Average latency per request
  • Error count and types
  • Request volume over time

Inference Metrics:

  • Token count (prompt + completion)
  • Generation speed (tokens/second)
  • Model used for each request
  • Time to first token

Server Explorer

The Server Explorer provides an interactive API reference:

Live Status:

  • Real-time server health indicators
  • Current port and configuration
  • Active model information
  • Memory and resource usage

Endpoint Browser:

  • Browse all available API endpoints
  • View endpoint documentation inline
  • See parameter schemas and types

Interactive Testing:

  • Edit request payloads directly
  • Send test requests with one click
  • View formatted JSON responses
  • Copy requests as cURL commands

Using Developer Tools

  1. Open the Management window with ⌘⇧M
  2. Select Insights for request monitoring
  3. Select Server for endpoint exploration

These tools are invaluable for:

  • Debugging integration issues
  • Optimizing prompt performance
  • Understanding API behavior
  • Testing new tool implementations

Resources

Documentation

Community

Security

Reporting Vulnerabilities

See SECURITY.md for reporting security issues.

Best Practices

  • Validate all inputs
  • Sanitize file paths in plugins
  • Use secure random for IDs
  • Log security-relevant events

To contribute, start with good first issues on GitHub.