# ElizaOS Developer Update — Week of 2026-04-27 to 2026-05-03

This week focused on (1) hardening the runtime for self-hosted + cross-platform clients, (2) eliminating ESM/CJS build incompatibilities across the plugin ecosystem, and (3) shipping a first-party secrets vault integrated into Settings and runtime operations.

---

## 1) Core Framework (Architecture / Runtime / Plugin System)

### ESM-only compatibility push across plugins
The ecosystem continued converging on an **ESM-only** world consistent with `@elizaos/core`. Multiple plugins removed incompatible CommonJS bundles to fix build/runtime breakage in ESM environments (notably `plugin-ollama`, `plugin-openai`, `plugin-openrouter`, `plugin-pdf`). This reduces “dual build” drift and avoids subtle interop failures in Bun/Node ESM resolution.

**Impact to plugin authors**
- If your plugin still ships `require()`-based entrypoints or CJS-only `exports`, expect breakage as more of the toolchain assumes ESM.
- Ensure your package uses ESM exports and that bundling doesn’t emit CJS shims that import ESM asynchronously.

### Self-hosted runtime connectivity hardening
Merged: **Self-hosted CORS + bearer auth + cross-platform build fixes** ([elizaos/eliza#7212](https://github.com/elizaos/eliza/pull/7212))

Key runtime changes:
- New `ELIZA_ALLOWED_ORIGINS` env to extend CORS allowlists (supports self-hosted dashboards at custom domains).
- Better support for **Capacitor WebView origins** (e.g. `capacitor://localhost`, `ionic://localhost`) for mobile builds.
- Unified bearer plumbing in the app-core API client: `fetchWithCsrf()` now attaches Authorization from boot config automatically.
- Auth status improvements for pairing flows (`/api/auth/status` now includes explicit `authenticated`).

### Secrets storage becomes a first-class runtime facility
Merged: **@elizaos/vault — cross-platform secrets vault + Settings UI integration** ([elizaos/eliza#7197](https://github.com/elizaos/eliza/pull/7197))

This introduces a new workspace package `@elizaos/vault` and wires it into Settings + runtime operations:
- AES-256-GCM encryption at rest
- Master key in OS keychain (macOS Keychain / Windows Credential Manager / Linux Secret Service)
- Headless fallback via passphrase-derived master key (scrypt)
- Settings “save API key” flows mirror sensitive values into the vault and reveal reads vault-first

### Prevent native segfaults on headless Linux (keychain / libsecret)
Merged: **skip OS keychain on headless Linux** ([elizaos/eliza#7230](https://github.com/elizaos/eliza/pull/7230))

On headless Linux without D-Bus, `@napi-rs/keyring` (libsecret backend) could crash the entire process at native init time. The fix:
- Detects unsafe keychain environments (Linux + missing `DBUS_SESSION_BUS_ADDRESS`, plus opt-out flags)
- Avoids eager native imports (lazy-load Entry class)
- Falls back to passphrase master key or throws a targeted error with remediation

### CI/CD reliability improvements
Merged: **Windows Server 2025 Inno Setup bogus exit codes** ([elizaos/eliza#7232](https://github.com/elizaos/eliza/pull/7232))

Windows desktop smoke tests now treat non-zero installer exit codes as success if the expected binaries were extracted (prevents false-negative CI failures).

---

## 2) New Features (with technical detail + examples)

### Feature: `@elizaos/vault` (encrypted secrets + multi-backend routing)
PR: [elizaos/eliza#7197](https://github.com/elizaos/eliza/pull/7197)

**What developers get**
- A consistent secrets API: `vault.set(key, value, { sensitive: true })` and `vault.get(key)`
- A “vault mirror” on plugin config writes: sensitive plugin fields are encrypted at rest automatically
- Optional references to external password managers (vault stores a resolver reference rather than plaintext)

**Example: storing a sensitive key**
```ts
import { sharedVault } from "@elizaos/vault";

const vault = sharedVault();

await vault.set("OPENAI_API_KEY", process.env.OPENAI_API_KEY!, { sensitive: true });

const key = await vault.get("OPENAI_API_KEY");
// Use `key` for provider initialization
```

**Headless Linux guidance**
If you’re deploying on headless Linux (no Secret Service / D-Bus), set a passphrase for the master key:
```bash
export MILADY_VAULT_PASSPHRASE='replace-with-strong-passphrase'
# optional explicit bypass
export MILADY_VAULT_DISABLE_KEYCHAIN=1
```

### Feature: Self-hosted browser + mobile clients can connect securely via CORS + bearer
PR: [elizaos/eliza#7212](https://github.com/elizaos/eliza/pull/7212)

**Enable CORS for your self-hosted UI domain**
```bash
export ELIZA_ALLOWED_ORIGINS="https://bot.example.com,https://admin.example.com"
```

**Bearer auth improvements**
- `/api/auth/me` supports bearer-only identity flows for machine clients
- App-core now centralizes “cookie + CSRF + bearer” logic via `fetchWithCsrf`

**Client-side example (conceptual)**
```ts
import { fetchWithCsrf } from "@elizaos/app-core/api/csrf-client";

// Authorization is auto-attached when boot config includes a token
const res = await fetchWithCsrf("/api/auth/me");
const me = await res.json();
```

### Feature: Plugin Jupiter migrated to `api.jup.ag` with mandatory API key
Completed work (tracked in daily summary): migration to new endpoint + authentication requirement.

**Operational implication**
- Your Jupiter integration now requires an API key (no anonymous access).
- Ensure the key is stored via Vault/Settings rather than plaintext env if shipping to end users.

---

## 3) Bug Fixes (critical fixes + technical context)

### Fixed: Headless Linux runtime segfault on boot (native keyring/libsecret)
PR: [elizaos/eliza#7230](https://github.com/elizaos/eliza/pull/7230)

**Root cause**
`@napi-rs/keyring` could abort at native layer when libsecret can’t reach D-Bus. Because the crash occurs during native initialization, JavaScript `try/catch` cannot intercept it.

**Resolution**
- Avoid module-eval-time native initialization via lazy imports
- Add environment-based guardrails and documented bypass paths

### Fixed: Cross-platform self-hosted auth regressions (CORS, bearer attachment, identity kind)
PR: [elizaos/eliza#7212](https://github.com/elizaos/eliza/pull/7212)

**Symptoms addressed**
- Capacitor WebView blocked by CORS preflight
- Remote dashboards unable to consistently authenticate
- Incorrect `/api/auth/me` identity `kind` in earlier implementations

### Fixed: Windows Server 2025 CI false failures for desktop installer
PR: [elizaos/eliza#7232](https://github.com/elizaos/eliza/pull/7232)

**Why it mattered**
Release pipelines were flaky due to Inno Setup exit codes that did not correlate with actual install success, causing re-runs and broken automation.

---

## 4) API Changes (developer-facing behavior changes)

### `ELIZA_ALLOWED_ORIGINS` (new)
PR: [elizaos/eliza#7212](https://github.com/elizaos/eliza/pull/7212)

- Adds operator-configurable CORS allowlist entries.
- Capacitor/Ionic origins are recognized explicitly to support mobile shells.

### Auth endpoints now expose clearer state
PR: [elizaos/eliza#7212](https://github.com/elizaos/eliza/pull/7212)

- `GET /api/auth/me`:
  - Accepts legacy bearer and can return a synthetic `kind: "machine"` identity when no owner is configured (improves self-hosting UX and corrects earlier mislabeling).
- `GET /api/auth/status`:
  - Adds `authenticated` boolean so clients can short-circuit pairing UI logic without inferring from `required`.

### Secrets reveal is now vault-first
PR: [elizaos/eliza#7197](https://github.com/elizaos/eliza/pull/7197)

- `POST /api/plugins/:id/reveal` prefers `sharedVault().get(key)` over `process.env` / `config.env` fallback.
- Plugin config writes mirror sensitive values into vault; failures are reported (not silently swallowed).

---

## 5) Social Media Integrations (Twitter / Telegram / Discord / Farcaster)

### Telegram: reliability issues under active investigation
Open issues:
- Dual poller race causing silent message loss: [elizaos/eliza#7245](https://github.com/elizaos/eliza/issues/7245)
- Token passing failures: [elizaos/eliza#7240](https://github.com/elizaos/eliza/issues/7240)
- Bun runtime errors around `bot.launch()`: [elizaos/eliza#7241](https://github.com/elizaos/eliza/issues/7241)

Work in progress:
- Apply Telegram setup token at runtime in plugin: [elizaos-plugins/plugin-telegram#29](https://github.com/elizaos-plugins/plugin-telegram/pull/29)

**Developer mitigation (until upstream is unified)**
If you are using a wrapper that starts its own Telegraf poller, ensure you do **not** also run `@elizaos/plugin-telegram` against the same token, or you can lose updates due to `getUpdates` being consumed by whichever poll wins.

```json
{
  "plugins": {
    "entries": {
      "@elizaos/plugin-telegram": { "enabled": false }
    }
  }
}
```

### Discord: env var standardization in progress
- Standardizing `DISCORD_AUTO_REPLY`: [elizaos-plugins/plugin-discord#50](https://github.com/elizaos-plugins/plugin-discord/pull/50)
- Config discrepancy discussion referenced as issue `#49` (plugin-discord repo): decide which env var path is canonical.

---

## 6) Model Provider Updates (OpenAI / Anthropic / DeepSeek / etc.)

### Anthropic SDK bump
Merged dependency update:
- `@anthropic-ai/sdk` → `^0.92.0` ([elizaos/eliza#7218](https://github.com/elizaos/eliza/pull/7218))

If you maintain provider adapters, re-run integration smoke tests around:
- streaming deltas format changes
- tool/function call serialization edge cases
- auth header behaviors

### AI SDK / OpenAI provider packages updated
Multiple Renovate bumps landed:
- `ai` v6.0.172 → v6.0.174 (e.g. [#7217](https://github.com/elizaos/eliza/pull/7217), [#7225](https://github.com/elizaos/eliza/pull/7225), [#7229](https://github.com/elizaos/eliza/pull/7229))
- `@ai-sdk/openai` v3.0.55 → v3.0.58 (e.g. [#7214](https://github.com/elizaos/eliza/pull/7214), [#7227](https://github.com/elizaos/eliza/pull/7227))
- `@ai-sdk/provider` and `@ai-sdk/provider-utils` bumps (e.g. [#7215](https://github.com/elizaos/eliza/pull/7215), [#7216](https://github.com/elizaos/eliza/pull/7216), [#7224](https://github.com/elizaos/eliza/pull/7224))

**Practical implication**
If your agent runtime pins specific provider behavior, watch for subtle changes in:
- retry semantics
- request shape normalization
- streaming event typing

---

## 7) Breaking Changes / Migration Warnings (V1 → V2 and ecosystem shifts)

### ESM-only core is increasingly non-negotiable
This week’s plugin build fixes underscore the direction: **plugins must be ESM-compatible**. If you are migrating older V1-era plugins:
- Remove CJS bundle outputs that attempt to `require("@elizaos/core")`
- Validate your `package.json` `exports` map supports ESM consumers cleanly
- Ensure tests run under both Node ESM and Bun

### Node.js v24 adoption underway
Node v24 upgrades have begun landing in the plugin ecosystem (e.g. `plugin-agent-wallet` dependency PRs; see [elizaos/eliza#7239](https://github.com/elizaos/eliza/pull/7239)). If you ship self-hosted stacks:
- verify native deps compatibility (keyring/libsecret, sqlite, etc.)
- verify CI runners and lockfiles are aligned

### Telegram integration currently has foot-guns during migration
Until issues [#7240](https://github.com/elizaos/eliza/issues/7240), [#7241](https://github.com/elizaos/eliza/issues/7241), and [#7245](https://github.com/elizaos/eliza/issues/7245) are resolved, treat Telegram enablement as requiring extra validation:
- confirm exactly one poller instance is running
- confirm token bridging into runtime env is correct
- run message burst tests to detect silent drops

---

## Notes from Developer/Community Discussions (Discord)

- A community member is building a multi-strategy **spot trading agent** on ElizaOS (SOL, SUI + 5 tokens), aiming for 1–2 signals/week during testing (Discord, 2026-05-02).
- Longer-lived agent reliability was discussed, including “memory rot” failure modes and mitigation ideas (freshness gates, reconciliation passes, re-embedding). This is not yet reflected as an upstream PR this week but is relevant for teams operating persistent agents.

---

## References
- Daily/overall engineering summary (May 2): https://elizaos.github.io/api/summaries/overall/day/2026-05-02.json
- PRs:
  - Vault: https://github.com/elizaos/eliza/pull/7197
  - Self-hosted auth/CORS: https://github.com/elizaos/eliza/pull/7212
  - Headless Linux keychain segfault fix: https://github.com/elizaos/eliza/pull/7230
  - Windows CI installer fix: https://github.com/elizaos/eliza/pull/7232
- Issues:
  - Telegram dual polling: https://github.com/elizaos/eliza/issues/7245
  - Telegram token bridge: https://github.com/elizaos/eliza/issues/7240
  - Telegram Bun launch error: https://github.com/elizaos/eliza/issues/7241