Skip to content

Nimi Avatar

Nimi Avatar is a first-party Tauri app (@nimiplatform/avatar) that puts an agent's character on the user's desktop as a transparent, always-on-top floating window. It is a separate app from Desktop — not a sub-surface — and the realization of "your agent is alive on your desktop."

What Nimi Avatar Is

PropertyValue
Package@nimiplatform/avatar
ShellTauri app, separate from Desktop
Window shapeTransparent + chrome-less + always-on-top (default; user-toggleable)
Mouse-event passthroughOutside the agent's body region, events pass through to underlying app
PositionDraggable; remembered across sessions
Click reactionsProgrammable through NimiAgentScript handlers
Companion stackAlways visible: assistant message bubble + status row + composer

It isn't a tray icon. It isn't a sidebar bubble. It is a present visual being living on the user's screen.

Embodiment Stage And Companion Surface

Avatar has two visible regions:

RegionPurpose
Embodiment StageThe main visible area where the agent's body renders (Live2D today)
Companion SurfaceAlways-visible stack: assistant-bubble + status-row + composer

The companion surface is always visible — no trigger button, no popup. It is docked next to the agent. Status row holds mic toggle, mode label, speaker indicator, settings cog. Composer is text input + send.

Composition State Machine

StateMeaning
loadingInitial bootstrap; no embodiment yet
readyStage and companion both mounted; agent is live
degraded:*Typed degradation reason (asset missing, runtime unavailable, etc.)
error:*Typed error reason
relaunch-pendingAwaiting Desktop launch update
fixture:activeFixture mode (development)

Hard mutual exclusion between ready and non-ready surfaces. Either both are ready or a degraded surface takes over.

NimiAgentScript (NAS)

NAS is the convention-based JS handler system for embodiment package creators.

Handler kindPath
Activity<model>/runtime/nimi/activity/<name>.js
Event<model>/runtime/nimi/event/<name>.js
Continuous<model>/runtime/nimi/continuous/<name>.js
Shared<model>/runtime/nimi/lib/

NAS handlers consume the embodiment projection API (backend- agnostic) and drive the backend (Live2D-specific extensions exposed when type-narrowed).

NAS handlers auto-register: runtime scans <model>/runtime/nimi/ and registers handlers; hot reload via Tauri notify watcher.

Window Behavior Details

DetailValue
DecorationsNone
Transparencyyes
Always-on-topDefault (user-toggleable)
Dynamic sizeFollows model bounds + companion footprint
Startup positionBottom-right with 24px padding
Subsequent positionsRemembered across sessions
Hit regionAlpha-mask + bbox dual-layer; pixel-level alpha sampling at 60Hz
Drag regionOnly inside embodiment-stage; companion + degraded absorb pointer events

These details add up to "the agent is on your screen, you can interact with it where it is, you can drag it, the rest of your screen still works."

Settings Popover

Only 4 toggles. Intentionally minimal:

ToggleDefault
always_on_topon
bubble_auto_openon
bubble_auto_collapseon
show_voice_captions(user choice)

No transcript-heavy panel. No workstation-style configuration. The Avatar app is an applet, not a workstation.

Reader Scenario: Opening Avatar From Desktop

You have an agent in Desktop chat. You want to bring them onto your screen.

  1. Desktop launches Avatar. Sends only agent_id + optional avatar_instance_id + optional launch_source. No tokens. No anchors. No package descriptors.
  2. Avatar bootstraps. Window create → renderer mount → emit avatar.app.start → register first-party app → resolve agent_id via Runtime account projection.
  3. Load visual package. Embodiment package + NAS handlers.
  4. Compute hit region. Alpha-mask + bbox.
  5. Mount stage + companion. State moves loading → ready.
  6. Emit avatar.app.ready. Agent is live.

Desktop is the launcher; Avatar is the carrier; Runtime is the authority.

Reader Scenario: Click Reactions Through NAS

The user clicks the agent's head; you want the agent to react.

  1. Click hits the embodiment stage. Alpha-mask determines that the click was inside the agent's body.
  2. avatar.user.click event. Emitted with hit region info.
  3. NAS event handler. A handler at <model>/runtime/nimi/event/onClickHead.js is auto-registered for this region.
  4. Handler runs. Triggers a shy reaction — runs an animation, plays a small sound, emits an emotion event.
  5. Embodiment projects. The Live2D backend renders the reaction.

The author of the embodiment package wrote the handler at a convention path. No registration ceremony.

Reader Scenario: Runtime Unavailable

Runtime daemon stops while Avatar is running.

  1. Runtime detection. Avatar detects the runtime is unreachable.
  2. State move. Composition state moves ready → degraded:runtime_unavailable.
  3. Degraded surface takes over. Stage + companion are both replaced by the degraded surface — typed reason visible to user.
  4. No silent fallback. Avatar doesn't pretend to operate without runtime; it does not silently switch to mock fixture.
  5. User options. Reload (after runtime returns) or close.

Recovery is manual: an explicit reload button only. No auto-self-healing from degraded back to ready. This prevents silently masking platform issues.

What Avatar Does Not Do

ConcernWhy not
Persistent transcriptLong history lives in Desktop chat
Background voice / wake wordVoice is explicit user-triggered
Continuation across screen lockVoice does not bridge across screen lock
Silent fallback to mockFail-closed on runtime unavailable
Auto-recovery from degradedManual reload only

Source Basis

Nimi AI open world platform documentation.