terminally online
your schizo AI waifu that actually respects your privacy
Milady is a personal AI assistant that is local-first by default and can also connect to Eliza Cloud or a remote self-hosted backend when you want hosted runtime access. Built on elizaOS.
Manages your sessions, tools, and vibes through a Gateway control plane. Connects to Telegram, Discord, whatever normie platform you use. Has a cute WebChat UI too.
tl;dr: local AI gf that's actually fast and doesn't phone home
Milady is not a full IDE: the product bet is fewer wasted GPU frames and wakeups when you are not looking at the app—especially on battery—while keeping the companion visually strong when you are. Background polling, off-screen WebGL, and battery-aware render quality are tuned toward that (see Desktop — battery and energy). Comparing to Cursor or other heavy dev tools is workload-dependent; the north star is great UX per watt for a local assistant, not matching an editor’s surface area.
If the VRM or Gaussian splat background fails only in the desktop build, the usual cause is two copies of three in the bundle (nested node_modules vs repo root), which breaks Spark’s splatDefines shader chunk. Milady forces one Three resolution path in Vite and isolates world-load failures so the avatar can still load. Why it matters: the companion is an agent surface (visibility + voice sync), not decoration. See Desktop VRM, Three.js, and Spark — WHYs.
When actions call HandlerCallback several times in one turn (same idea as Discord progressive messages), the Milady API replaces the last action-produced segment in the SSE stream instead of concatenating every status line. Why: Live status should read like edits to one message, not a glued blob. The elizaOS contract stays callback({ text, source }). Docs: Action callbacks and SSE streaming.
Milady ships with native BNB Smart Chain (BSC) support — your agent can trade tokens, track meme launches, and interact with DeFi on BSC out of the box.
The built-in EXECUTE_TRADE action lets your agent swap tokens on BSC via PancakeSwap. Supports buy/sell with configurable slippage.
To enable BSC trading, add to your .env or ~/.local/state/milady/.env:
EVM_PRIVATE_KEY=0x... # wallet private key (hex, 0x-prefixed)
ELIZA_TRADE_PERMISSION_MODE=agent # "agent" for autonomous, "user" for manual confirm
Optional RPC configuration (defaults to public BSC RPC):
ALCHEMY_API_KEY=... # or use ANKR_API_KEY / INFURA_API_KEY
EVM_RPC_PROVIDER=alchemy # alchemy | infura | ankr | elizacloud
Once configured, just tell your agent: "buy 0.1 BNB of " or "sell all my ".
Install the meme-rush skill from Binance Skills Hub to track meme token launches across BSC and Solana:
Install from the Skills Marketplace in the app, or ask your agent to install it.
Milady auto-generates EVM and Solana wallet addresses on startup. For BSC trading you need to import your own private key (see above). If connected to Eliza Cloud, managed wallets via Steward are available without local key management.
View your agent's wallet addresses in the Settings tab or ask: "what's my wallet address?"
Grab from Releases:
| Platform | Download | |
|---|---|---|
| macOS (Apple Silicon) | latest macOS installer | for your overpriced rectangle |
| macOS (Intel) | latest macOS installer | boomer mac (why separate arm64/x64: Build & release) |
| Windows | latest Windows installer | for the gamer anons |
| iOS | App Store (coming soon) | for the privacy-pilled |
| Android | Google Play / APK | for the degen on the go |
| Linux | stable-linux-x64-Milady-Setup.tar.gz |
I use arch btw — see Linux install |
Signed and notarized. No Gatekeeper FUD. We're legit.
cd ~/Downloads
curl -fsSLO https://github.com/milady-ai/milady/releases/latest/download/SHA256SUMS.txt
shasum -a 256 --check --ignore-missing SHA256SUMS.txt
Milady → Reset Milady… (menu bar) confirms in the native dialog, then the main process calls POST /api/agent/reset, restarts the agent (embedded or external API), and tells the renderer to apply the same local state wipe as the end of Settings reset (onboarding, API client, cloud UI, conversations). Why main does HTTP: on macOS/WKWebView, the webview can fail to run fetch immediately after a native dialog, so a renderer-only reset looked stuck. Why the renderer still runs teardown: one implementation of “clear UI + MiladyClient” avoids duplicating logic in TypeScript main vs React.
MILADY_DISABLE_EDGE_TTS=1 — see Environment variables and TTS plugincurl -fsSL https://get.milady.ai | bash
milady setup
Then start Milady:
milady
First run walks you through onboarding:
…
Windows:
irm https://get.milady.ai/install.ps1 | iex
NPM global:
npm install -g miladyai
milady setup
Milady builds against the published @elizaos/* npm packages (beta dist-tag) by default. The repo no longer tracks eliza/ as a submodule — a fresh clone has no eliza/ checkout and bun install resolves everything from npm.
First install after cloning:
git clone https://github.com/milady-ai/milady.git
cd milady
./install # Unix / macOS — chmod +x install if needed
# install.cmd on Windows
# With no args, the wrapper opens a Space/Enter multi-select picker:
# packages, local elizaOS source, or all developer paths.
# Non-interactive examples:
./install --profile packages
./install --profile local
./install --profile all
# Plain `bun install` is package-mode only and runs a preflight doctor.
# If Node/Python is outside the supported native install lane, run ./install.
Milady has two source modes for @elizaos/* packages, selected via MILADY_ELIZA_SOURCE:
| Mode | When to use | What resolves @elizaos/* |
|---|---|---|
packages (default) |
App development, builds, releases | npm registry (beta dist-tag) |
local |
Patching elizaOS upstream alongside Milady | A repo-local eliza/ checkout linked into node_modules/ |
Switch to local mode (uneject) — clones eliza/ if absent, links workspace packages, swaps the root tsconfig to source-priority paths:
bun run eliza:local # clone (or restore) eliza/, link packages, run bun install
Switch back to packages mode (eject) — rewrites the root package.json to pin npm versions, swaps the root tsconfig back to packages-mode-clean, and regenerates the lockfile:
bun run eliza:packages # default: beta tag
bun run eliza:packages:alpha # explicit alpha (legacy)
bun run eliza:packages -- --tag beta # any other dist-tag
bun run eliza:packages -- --version 2.0.0-alpha.116 # pin an exact version
bun run eliza:packages -- --rename # also rename eliza/ → .eliza.ci-disabled/
What each mode mutates — both kept in sync by scripts/lib/tsconfig-mode.mjs:
tsconfig.json — sourced from scripts/templates/tsconfig.packages-mode.json (default) or scripts/templates/tsconfig.local-mode.json (local)package.json — rewritten on eject (backup at package.json.pre-disable-backup); restored on unejectbun.lock — regenerated on every mode switcheliza/ directory — left in place by default; renamed to .eliza.ci-disabled/ only with --renameThe checked-in tsconfig.json always matches the packages-mode template; the standalone contract test enforces this invariant. Run bun run verify:standalone to check.
Configuration env vars (read by scripts/lib/eliza-package-mode.mjs):
MILADY_ELIZA_SOURCE — local or packages (default)MILADY_ELIZAOS_DIST_TAG / ELIZAOS_NPM_TAG — npm dist-tag in packages mode (default beta)MILADY_ELIZAOS_VERSION — pin an exact versionMILADY_ELIZA_GIT_URL / MILADY_ELIZA_BRANCH — override the eliza source clone targetMILADY_SKIP_LOCAL_UPSTREAMS=1 — legacy flag equivalent to MILADY_ELIZA_SOURCE=packagesTest coverage in each mode:
bun run test, bun run verify:typecheck, bun run verify:lint, bun run build:web, bun run build:android — work in both modes.bun run build:desktop and bun run build:ios (plus dev:desktop) require local mode first (bun run eliza:local). Packages mode ships no platforms/ directory, so the published @elizaos/app-core tarball has nothing for Electrobun / the iOS Capacitor shell to resolve against.apps/app/test/electrobun-packaged/ requires local mode (it imports source-level test helpers from eliza/packages/app-core/test/helpers/).Bun's cache stores packages in deep directory trees that exceed the default Windows MAX_PATH limit (260 characters). Native builds (e.g. llama-cpp-capacitor via CMake/ninja) will fail with mkdir: No such file or directory unless long paths are enabled at the OS level.
Run once in an elevated PowerShell, then reboot:
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" `
-Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
Also enable long paths in Git:
git config --global core.longPaths true
brew tap milady-ai/tap
brew install milady-ai/tap/milady # CLI
brew install --cask milady-ai/tap/milady # Desktop app (macOS only)
The Linux desktop app ships as a single installer tarball: stable-linux-x64-Milady-Setup.tar.gz on the latest release. There is no AppImage, .deb, Snap, Flatpak, or APT repo today.
cd ~/Downloads
curl -fsSLO https://github.com/milady-ai/milady/releases/latest/download/stable-linux-x64-Milady-Setup.tar.gz
tar -xzf s
No open issues yet, or sync has not completed.