Skip to content

Latest commit

 

History

History
42 lines (31 loc) · 9.99 KB

File metadata and controls

42 lines (31 loc) · 9.99 KB

Changelog

All notable changes to Milady are documented here. Format is Keep a Changelog.

[Unreleased]

Added

  • Companion UI — VRM engine, animations, themes, i18n: 3D VRM avatar engine with animation system (idle, wave, dance, retargeting), companion view with chat integration, bubble emotes, theme switching, full i18n support (en, zh-CN), and plugin logos for installed ElizaOS plugins. Includes BSC wallet trading panel, wallet portfolio display, and trading profile modal. (#812) thanks @Dexploarer
  • Release workflow documentation (WHYs): docs/build-and-release.md now has a "Release workflow: design and WHYs" section explaining strict shell, retry assertions, @electron/asar crash dump, find/read safety, DMG path robustness, node-gyp artifact removal, size report scope, single Capacitor build step, and packaged DMG E2E timeout/dump. Why: Future maintainers and agents need to know why these choices exist so they don't "fix" or remove them incorrectly.
  • Multi-destination streaming registry: Replace single destination? with Map<string, StreamingDestination> + activeDestinationId, enabling runtime switching between streaming targets via POST /api/streaming/destination. New getActiveDestination() helper provides backward-compatible fallback for single-destination configs. (#788) thanks @Dexploarer
  • pump.fun streaming plugin: @milady/plugin-pumpfun-streaming adds pump.fun RTMP destination using the shared createStreamingPlugin() factory. (#788) thanks @Dexploarer
  • X/Twitter streaming plugin: @milady/plugin-x-streaming adds X/Twitter RTMPS destination using the shared factory. (#788) thanks @Dexploarer
  • RTMP URL validation: getCredentials() in plugin-streaming-base now throws early with a clear error when RTMP URL is not configured. (#788) thanks @Dexploarer
  • Plugin resolution and NODE_PATH (doc): docs/plugin-resolution-and-node-path.md explains why we set NODE_PATH in three places so dynamic plugin imports resolve from CLI, desktop dev, and direct eliza load. Why: Prevents "Cannot find module '@elizaos/plugin-...'" when entry is under dist/ or cwd is a subdir.
  • Electron startup resilience: The desktop app now keeps the API server running when the agent runtime fails to load (e.g. missing native module like onnxruntime_binding.node). Why: Without this, a single load failure would throw, the outer catch would tear down the API server, and the renderer would get no port and show only "Failed to fetch" with no error message. Keeping the server up and setting state: "error" with port preserved lets the UI connect and show "Agent unavailable: …" with the actual error. See docs/electron-startup.md and WHY comments in apps/app/electron/src/native/agent.ts — do not remove the try/catch and .catch() guards as "excess" exception handling.
  • Regression tests for startup resilience: apps/app/test/electron-ui/electron-startup-failure.e2e.spec.ts now has two tests: (1) failed runtime keeps API server alive and recovery on retry, (2) failed eliza.js load (e.g. missing native binding) preserves port and no server teardown. Why: A failing test is strictly stronger than documentation for preventing regressions; if someone removes the guards, CI fails.

Changed

  • Node.js CI timeouts: Test and other CI workflows no longer rely on actions/setup-node@v4 for Node. On Blacksmith runners we use useblacksmith/setup-node@v5 (colocated cache); on GitHub-hosted runners we pin actions/setup-node@v3 and set check-latest: false. We also add Bun global cache (~/.bun/install/cache) and timeout-minutes to test, release, nightly, benchmark-tests, and publish-npm. Why: v4’s slow post-action and nodejs.org downloads caused frequent timeouts; Blacksmith’s action avoids the download on their runners; v3 + no check-latest uses toolcache and avoids the regression. Caching and timeouts keep runs fast and bounded. See docs/build-and-release.md "Node.js and Bun in CI: WHYs".
  • Release workflow hardening: .github/workflows/release.yml — (1) Job default shell set to bash -euo pipefail so steps fail on first error. (2) All bun install retry loops now run the same install command once after the loop so the step fails if all retries failed. (3) Crash dump uses npx @electron/asar list instead of deprecated asar. (4) Bundle dist and node-gyp removal use find -print0 and while IFS= read -r -d '' for paths with special characters. (5) DMG path for packaged E2E uses find + stat -f (newest by mtime) instead of ls -t. (6) Size report uses if [ -d ... ] guards and includes milady-dist. (7) Single "Build Capacitor app" step for all platforms. Why: Reproducible, fail-fast builds and diagnosable failures; see docs/build-and-release.md.
  • Packaged DMG E2E: CDP wait timeout is 240s in CI (120s locally); on CDP wait or connect failure we dump app stdout/stderr before throwing. Why: CI can be slower; longer timeout reduces flakiness; log dump makes timeouts debuggable.
  • Coding agent is core, not optional: @elizaos/plugin-coding-agent remains in CORE_PLUGINS so it is always auto-loaded. Why: Required for PTY/coding flows; optional would mean it is not in the default load set.
  • NODE_PATH for plugin resolution: scripts/run-node.mjs sets NODE_PATH for the spawned child so dist/eliza.js can resolve @elizaos/*. src/runtime/eliza.ts prepends repo root node_modules on load when not already set (dedupe). Electron: packaged uses ASAR node_modules; dev walks up from __dirname to find monorepo root (no fixed depth). All call Module._initPaths() so Node re-reads NODE_PATH. Why: Dynamic import("@elizaos/plugin-...") only works when Node knows where to look; see docs/plugin-resolution-and-node-path.md.
  • NFA routes: optional @milady/plugin-bnb-identity: /api/nfa/status and /api/nfa/learnings now lazy-load the plugin via dynamic import() and fall back when the package is missing (empty Merkle root, empty entries). Tests mock the plugin so they pass without the workspace package. Why: Core can be built and tested without the plugin; installs or CI that don’t have the plugin still get a working API. An ambient declaration in src/types/optional-plugin-modules.d.ts lets TypeScript resolve the dynamic import even when packages/ is excluded from the build.
  • CI / Mac binary build: Plugin and dependency copy for the Electron bundle is now derived automatically from each copied @elizaos package's package.json dependencies (see scripts/copy-electron-plugins-and-deps.mjs). Why: A curated list was a maintenance burden and caused silent failures when new plugin runtime deps were added. Walking the dependency graph ensures we copy everything plugins need; we skip known dev/renderer-only packages (e.g. typescript, lucide-react) to avoid bloat. macOS x64 builds run root and Electron installs under arch -x86_64 so native modules get x64 binaries on Intel Macs. Whisper universal binary is built in release; electron test jobs no longer use continue-on-error on every step; Bun install cache and verify-build.sh arch detection added.

Fixed

  • Windows release build (plugin-bnb-identity prepare): The plugin’s build script ran npx tsc for declaration emit; on Windows CI this resolved to the joke npm package tsc instead of the TypeScript compiler, so the prepare step failed. Why: We now use npx -p typescript tsc so the compiler is taken from the typescript package explicitly. See comment in packages/plugin-bnb-identity/build.ts.
  • Release workflow size-report step (Linux/macOS): The du | sort | head pipelines could exit with 141 (SIGPIPE) and, under bash -euo pipefail, the step exited before the r=$? check ran, failing the job. Why: We wrap each pipeline in a subshell and use ( pipeline ) || r=$? so 141 doesn’t trigger errexit, then explicitly allow 0 or 141. We also redirect sort stderr to avoid "Broken pipe" noise. See docs/build-and-release.md and the step comment in release.yml.
  • Intel Mac desktop app: Packaged DMG could fail with "Cannot find module .../darwin/x64/onnxruntime_binding.node" because CI runs on arm64 runners and was shipping arm64 native binaries. Why: Native Node addons (e.g. onnxruntime-node) are built for the install host's arch; installing and building under arch -x86_64 (Rosetta) produces x64 .node files so the Intel DMG works.
  • Electron agent startup: If eliza.js failed to load (e.g. due to the above), the whole startup threw and the outer catch closed the API server. Why: We now isolate failures (.catch() on eliza import, try/catch around startEliza()), keep the API server up, and set state: "error" with port preserved so the renderer can display the error instead of "Failed to fetch".
  • Plugin resolution (@elizaos/plugin-coding-agent and others): Dynamic import("@elizaos/plugin-*") from dist/eliza.js or milady-dist/eliza.js failed with "Cannot find module" because Node's resolution did not reach repo root node_modules. Why: We set NODE_PATH in three places (eliza.ts on load, run-node.mjs for the CLI child, Electron agent for dev/packaged); see docs/plugin-resolution-and-node-path.md.
  • Bun + @elizaos/plugin-coding-agent: Under bun run dev, the plugin failed to load with "Cannot find module … from …/src/runtime/eliza.ts" even though the package was installed. Why: The published npm package has exports["."].bun = "./src/index.ts"; that path exists only in the upstream dev workspace, not in the tarball. Bun's resolver picks the "bun" condition first and does not fall back to "import" when the file is missing. We patch the package's package.json in scripts/patch-deps.mjs (postinstall) to remove the dead bun/default conditions so Bun resolves via "import"./dist/index.js. See "Bun and published package exports" in docs/plugin-resolution-and-node-path.md.

[2.0.0-alpha.71] and earlier

See Releases for version history.