Skip to content

Lexiie/miku

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

54 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Miku

Miku

Demo

watch demo

Build Release APK Build Debug APK Deploy Docker ElizaOS Deploy Nosana Android ElizaOS Kotlin TypeScript License: MIT

Your Personal AI Assistant for Android Automation

Miku transforms natural language into native Android actions. No more tapping through menus, just tell Miku what you want, and it happens instantly.

Built on ElizaOS with decentralized inference, Miku bridges conversational AI with deep Android system integration, giving you voice-controlled automation that runs on your terms.


🎯 What Makes Miku Different

True Native Integration β€” Unlike chatbots that only reply with text, Miku executes real Android API calls. Set alarms, toggle WiFi, send SMS, control brightness, and launch apps through natural language.

Decentralized Intelligence β€” Your agent runs on Nosana's distributed GPU network instead of a traditional centralized host. You control the infrastructure and keep the Android execution layer on your own device.

Fast to Start β€” Deploy the agent, install the app, connect the endpoint, and start automating. The repo keeps the moving pieces separated so the path from clone to demo stays simple.

Hybrid Architecture β€” ElizaOS handles intent parsing and response formatting, while native Android APIs handle execution. That split keeps the assistant flexible without giving up local device control.


✨ Capabilities

⏰ Time Management

  • Set Alarm β€” "Set alarm for 7 AM tomorrow"
  • Set Timer β€” "Timer for 10 minutes"
  • Calendar Events β€” "Add meeting with John at 2 PM"
  • View Schedule β€” "What's on my calendar today?"
  • Reminders β€” "Remind me to call mom in 30 minutes"

πŸ“± Communication

  • Send SMS β€” "Text 081234567890 saying I'm running late"
  • Make Calls β€” "Call 081234567890"
  • Notifications β€” "Notify me to take a break"

πŸ”§ System Control

  • WiFi β€” "Turn on WiFi" / "Disable WiFi"
  • Bluetooth β€” "Enable Bluetooth"
  • Flashlight β€” "Turn on flashlight"
  • Brightness β€” "Set brightness to 80%"
  • Volume β€” "Set volume to 50%"
  • Ringer Mode β€” "Set phone to silent" / "Vibrate mode"

πŸ“ Location & Apps

  • Get Location β€” "Where am I?"
  • Open Apps β€” "Open Spotify"
  • Uninstall Apps β€” "Uninstall Twitter"

πŸ—οΈ Architecture

Miku uses a hybrid client-server architecture where intelligence lives remotely and execution happens locally:

diagram

Why This Architecture?

  • Separation of Concerns β€” AI inference happens on remote compute, execution happens locally on the device
  • Privacy β€” Sensitive actions such as SMS and calls never need to be executed in the cloud
  • Scalability β€” One agent can serve multiple devices while each phone keeps its own permissions and execution state
  • Flexibility β€” You can change prompts, models, and deploy settings without rewriting the Android app

πŸš€ Quick Start

Prerequisites

  • Docker Hub account
  • GitHub account with Actions enabled
  • Nosana API key from deploy.nosana.com
  • Gemini API key for the current GitHub Actions deploy flow
  • Android device (API 26+)

Step 1: Configure GitHub Secrets

Go to your repo β†’ Settings β†’ Secrets and variables β†’ Actions, then add:

Secret Value Where to Get
DOCKER_USERNAME Your Docker Hub username hub.docker.com
DOCKER_PASSWORD Docker Hub access token hub.docker.com/settings/security
NOSANA_API_KEY Nosana API key deploy.nosana.com/account
GEMINI_API_KEY Gemini API key required by the current workflow Google AI Studio or Google Cloud

The Docker workflow uses DOCKER_USERNAME to tag the image automatically, so you do not need to hardcode the image name in the repository first.

Miku started with Qwen 3.5 27B as the reference model, but the agent layer can be adapted to other LLMs you wire into ElizaOS, for example OpenAI-compatible endpoints, Claude, GLM, and similar provider integrations.

The checked-in Nosana deploy workflow in this repo currently deploys with GEMINI_API_KEY, so if you switch providers or models, update that workflow and the runtime environment together.

Step 2: Run the Manual Workflows

Run these workflows manually from the Actions tab:

  1. Deploy Docker ElizaOS Builds and pushes the agent image to Docker Hub.
  2. Build Debug APK or Build Release APK Produces the Android artifact you want to install.
  3. Deploy Nosana Starts the Nosana deployment using the Docker image tag you choose, usually latest or a specific commit SHA.

Step 3: Install & Connect

  1. Download the APK from the workflow artifact of Build Debug APK or Build Release APK.
  2. Install it on your Android device.
  3. Get the agent URL from the Nosana dashboard.
  4. Open the Miku app, enter the URL, and tap Connect.
  5. Start automating.

πŸ› οΈ Technical Deep Dive

Intent Parsing Engine

Miku uses a custom ElizaOS action flow that parses natural language into structured JSON:

// Input: "Set alarm for 7 AM tomorrow"
// Output:
{
  "text": "⏰ Alarm set for 7:00 AM",
  "actions": [{
    "type": "SET_ALARM",
    "params": {
      "hour": 7,
      "minute": 0,
      "label": "Alarm"
    }
  }]
}

The parser handles:

  • Time extraction β€” Relative ("in 10 minutes") and absolute ("7 AM")
  • Parameter inference β€” Smart defaults when information is missing
  • Phone number extraction β€” SMS and call targets from plain text
  • Multi-action commands β€” "Turn on WiFi and set brightness to 50%"

Android Execution Layer

AutomationExecutor.kt maps action types to native Android APIs:

Action Type Android API Permission Required
SET_ALARM Intent(AlarmClock.ACTION_SET_ALARM) None
SEND_SMS SmsManager.sendTextMessage() SEND_SMS
TOGGLE_WIFI WifiManager.setWifiEnabled() CHANGE_WIFI_STATE
SET_BRIGHTNESS Settings.System.putInt() WRITE_SETTINGS
GET_LOCATION FusedLocationProviderClient ACCESS_FINE_LOCATION
TOGGLE_FLASHLIGHT CameraManager.setTorchMode() CAMERA

Permission Handling β€” Miku requests permissions just-in-time. When you first send SMS, it asks for SMS permission. When you first set brightness, it opens system settings.

For exact scheduled reminders, Miku separately requests Android's exact alarm capability when needed.

Communication Protocol

Health Check:

GET /health

Request:

POST /api/chat
{
  "text": "Set alarm for 7 AM and turn on WiFi",
  "userId": "android_user"
}

Response:

{
  "text": "Alarm ready for 07:00. WiFi will be turned on",
  "actions": [
    {
      "type": "SET_ALARM",
      "params": {
        "hour": 7,
        "minute": 0,
        "label": "Alarm"
      }
    },
    {
      "type": "TOGGLE_WIFI",
      "params": {
        "enable": true
      }
    }
  ]
}

The Android app checks /health before connecting, executes each action sequentially, and displays follow-up status updates in the chat for async actions such as location lookup.

State Management

Miku uses Jetpack Compose + ViewModel for reactive UI:

  • ChatViewModel β€” Manages messages, connection state, and API calls
  • AutomationExecutor β€” Stateless executor for Android APIs
  • ApiClient β€” Retrofit HTTP client with URL normalization and health checks

No local storage is required, all state is ephemeral by design.


πŸ“¦ Project Structure

miku/
β”œβ”€β”€ src/                                    # ElizaOS Agent
β”‚   β”œβ”€β”€ parser.ts                           # Shared natural-language -> action parser
β”‚   β”œβ”€β”€ actions/
β”‚   β”‚   └── androidAutomation.ts            # Eliza action wrapper for parser output
β”‚   β”œβ”€β”€ api.ts                              # Plugin routes (/api/chat, /health)
β”‚   └── index.ts                            # Plugin entry point
β”‚
β”œβ”€β”€ android/                                # Android App
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ build.gradle.kts                # Build config
β”‚   β”‚   └── src/main/
β”‚   β”‚       β”œβ”€β”€ AndroidManifest.xml         # Permissions & config
β”‚   β”‚       β”œβ”€β”€ java/com/miku/
β”‚   β”‚       β”‚   β”œβ”€β”€ MainActivity.kt         # Compose UI
β”‚   β”‚       β”‚   β”œβ”€β”€ ChatViewModel.kt        # State management
β”‚   β”‚       β”‚   β”œβ”€β”€ ApiClient.kt            # HTTP client
β”‚   β”‚       β”‚   β”œβ”€β”€ AutomationExecutor.kt   # Android API executor
β”‚   β”‚       β”‚   β”œβ”€β”€ ReminderReceiver.kt     # Reminder notifications
β”‚   β”‚       β”‚   └── Models.kt               # Data classes
β”‚   β”‚       └── res/
β”‚   β”‚           β”œβ”€β”€ values/strings.xml
β”‚   β”‚           └── values/themes.xml
β”‚   β”œβ”€β”€ build.gradle.kts                    # Root build file
β”‚   β”œβ”€β”€ settings.gradle.kts                 # Project settings
β”‚   └── gradlew                             # Gradle wrapper
β”‚
β”œβ”€β”€ characters/
β”‚   └── android.character.json              # Agent personality & examples
β”‚
β”œβ”€β”€ nos_job_def/
β”‚   └── nosana_eliza_job_definition.json    # Nosana deployment config template
β”‚
β”œβ”€β”€ .github/workflows/
β”‚   β”œβ”€β”€ android-release.yml                 # Manual release APK build
β”‚   β”œβ”€β”€ build-debug-apk.yml                 # Manual debug APK build
β”‚   β”œβ”€β”€ deploy-docker-elizaos.yml           # Manual Docker build/push
β”‚   └── deploy-nosana.yml                   # Manual Nosana deployment
β”‚
β”œβ”€β”€ Dockerfile                              # Container config
β”œβ”€β”€ package.json                            # Node dependencies
└── README.md                               # This file

πŸ”§ Development

Local Agent Development

# Install dependencies
pnpm install

# Copy environment template
cp .env.example .env

# Start the agent in development mode
pnpm dev

For local Ollama development, .env.example includes an example OpenAI-compatible setup.

Default Model Routing

By default, Miku now uses a Nosana OpenAI-compatible endpoint with:

  • MODEL_NAME=Qwen3.5-9B-FP8
  • OPENAI_API_URL=https://5i8frj7ann99bbw9gzpprvzj2esugg39hxbb4unypskq.node.k8s.prd.nos.ci/v1

For embeddings, .env.example also includes:

  • OPENAI_EMBEDDING_URL=https://4yiccatpyxx773jtewo5ccwhw1s2hezq5pehndb6fcfq.node.k8s.prd.nos.ci/v1
  • OPENAI_EMBEDDING_MODEL=Qwen3-Embedding-0.6B

Conversation fallback order in src/conversation.ts is:

  1. OpenAI-compatible provider (Nosana/Qwen default)
  2. Gemini fallback (GEMINI_API_KEY) if primary provider is unavailable

If both providers are unavailable, Miku keeps parser-only behavior for automation commands and skips conversational LLM replies.

Agent runs on http://localhost:3000

Android App Development

cd android

# Debug build
./gradlew assembleDebug

# Install to connected device
./gradlew installDebug

# Release build
./gradlew assembleRelease

APK output: android/app/build/outputs/apk/

Testing Locally

  1. Get your computer's local IP.
  2. Run the agent locally with pnpm dev.
  3. In the Miku app, enter http://YOUR_LOCAL_IP:3000.
  4. Ensure the phone and computer are on the same WiFi network.

🚒 Deployment

Manual GitHub Actions Deployment (Recommended)

GitHub Actions handles the maintained deployment path for this repo, but each workflow is triggered manually.

If you already followed Quick Start, there is no extra setup here. Run the workflows in the order you need:

  1. deploy-docker-elizaos.yml
  2. build-debug-apk.yml or android-release.yml
  3. deploy-nosana.yml

Manual Deployment

The maintained manual flow lives in these workflow files:

  • .github/workflows/android-release.yml
  • .github/workflows/build-debug-apk.yml
  • .github/workflows/deploy-docker-elizaos.yml
  • .github/workflows/deploy-nosana.yml

The Nosana deployment flow uses:

  • market discovery via /api/markets/
  • deployment creation via /api/deployments/create
  • deployment start via /api/deployments/{id}/start

πŸ“± Android App Features

Chat Interface

  • Material Design 3 β€” Modern, clean UI with dynamic theming
  • Real-time messaging β€” Instant feedback on action execution
  • Auto-scroll β€” Always shows the latest messages

Endpoint Configuration

  • Manual URL input β€” Connect to any compatible ElizaOS agent
  • Health checks β€” Validates the endpoint before chat requests begin
  • Error handling β€” Graceful fallback on network issues

Permission Management

  • Just-in-time requests β€” Only asks when needed
  • Clear explanations β€” Shows why each permission is required
  • Graceful degradation β€” Continues working even if some permissions are denied

Execution Feedback

Every action shows:

  • βœ… Success confirmation
  • ⚑ Action type executed
  • πŸ“Š Result details when available

πŸ” Security & Privacy

Privacy-First Design:

  • No data collection or analytics
  • No cloud storage of messages
  • All sensitive actions such as SMS and calls execute locally
  • Agent only receives command text, not contact lists or other device-private datasets

Permission Model:

  • Runtime permissions requested on-demand
  • User has full control over what Miku can access
  • Permissions can be revoked anytime via Android settings

Network Security:

  • Deployed endpoints should use HTTPS whenever available
  • The Android app currently allows cleartext traffic, which is useful for local development and LAN testing
  • No authentication tokens stored on device

πŸ§ͺ Testing

Test Commands

Try these to verify key features:

⏰ Time Management:
- "Set alarm for 7 AM"
- "Set timer 5 minutes"
- "Add meeting tomorrow at 2 PM"

πŸ”§ System Control:
- "Turn on WiFi"
- "Set brightness to 70%"
- "Turn on flashlight"
- "Set phone to silent"

πŸ“± Communication:
- "Send SMS to 081234567890 saying hello"
- "Notify me to take a break"

πŸ“ Location:
- "Where am I?"

πŸ“± Apps:
- "Open Chrome"

Troubleshooting

Issue Solution
Can't connect to agent Verify URL format: https://xxx.node.k8s.prd.nos.ci for deployed endpoints, including the protocol.
Permission denied Grant permission when prompted, or check Settings β†’ Apps β†’ Miku β†’ Permissions.
Action not executing Check Logcat for errors: adb logcat | grep Miku.
Agent not responding Check the latest GitHub Actions run and the Nosana dashboard for deployment status.
Build fails Ensure JDK 17 is installed: java -version.
Gradle sync fails Delete .gradle and sync again.

🎨 Customization

Modify Agent Behavior

Edit characters/android.character.json:

{
  "name": "Miku",
  "system": "Your custom instructions here...",
  "messageExamples": [
    // Add more examples to improve parsing accuracy
  ]
}

Add New Actions

1. Add to shared parser (src/parser.ts):

if (lowerText.includes("screenshot")) {
  pushAction(actions, {
    type: "TAKE_SCREENSHOT",
    params: {}
  });
}

2. Add to Executor (android/.../AutomationExecutor.kt):

"TAKE_SCREENSHOT" -> takeScreenshot(action.params)

3. Implement Android API:

private fun takeScreenshot(params: Map<String, Any>): String {
    // Your implementation
    return "βœ… Screenshot saved"
}

Extend with ElizaOS Plugins

Add more capabilities:

pnpm add @elizaos/plugin-web-search

Update characters/android.character.json:

{
  "plugins": [
    "@elizaos/plugin-bootstrap",
    "@elizaos/plugin-openai",
    "@elizaos/plugin-web-search"
  ]
}

πŸ—οΈ Tech Stack

Backend (ElizaOS Agent)

  • Framework: ElizaOS v2
  • Runtime: Node.js
  • Reference model: Qwen3.5-27B
  • Model layer: OpenAI-compatible endpoints plus other ElizaOS integration paths such as Claude, GLM, and similar providers
  • Local dev option: Ollama-compatible OpenAI endpoint
  • Inference host: Nosana decentralized GPU network
  • API: ElizaOS plugin routes (/api/chat, /health)
  • Container: Docker

Frontend (Android App)

  • Language: Kotlin
  • UI Framework: Jetpack Compose (Material Design 3)
  • Architecture: MVVM (ViewModel + State)
  • HTTP Client: Retrofit + OkHttp
  • Async: Kotlin Coroutines
  • Location: Google Play Services FusedLocationProvider
  • Min SDK: 26 (Android 8.0)
  • Target SDK: 35 (Android 15)

Infrastructure

  • Compute: Nosana decentralized network
  • CI/CD: GitHub Actions
  • Container Registry: Docker Hub
  • Deployment: Automated via GitHub workflow

πŸ“Š Performance

Agent Response Time:

  • Intent parsing: ~500ms
  • Total round-trip: <2s including network

Android Execution:

  • Action execution: <100ms for native APIs
  • UI update: instant through Compose reactivity

Resource Usage:

  • APK size: ~8MB
  • Memory footprint: ~50MB
  • Battery impact: minimal with no persistent background service requirement

🀝 Contributing

Contributions welcome. Areas for improvement:

  • Voice input integration (SpeechRecognizer)
  • Multi-step action sequences
  • Action history & undo
  • Widget support
  • Tasker integration
  • More Android APIs (camera, media, sensors)

πŸ“„ License

MIT License - see LICENSE file.


πŸ™ Acknowledgments

Built with:

  • ElizaOS - AI agent framework
  • Nosana - Decentralized compute
  • Qwen - Open-source model family used as the original reference point

Miku β€” Your device, your assistant, your control. πŸ€–βœ¨

About

Your device, your assistant, your control. πŸ€–βœ¨

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors