npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@avatar-engine/core

v1.3.0

Published

Framework-agnostic core for Avatar Engine — types, WebSocket protocol, state machine, configuration

Readme

@avatar-engine/core

npm TypeScript License

Framework-agnostic core for Avatar Engine — TypeScript types, WebSocket protocol state machine, and a ready-to-use client class.

Use this package directly when building with Vue, Svelte, vanilla JS, or any non-React framework. React users should install @avatar-engine/react instead (it re-exports everything from core).

Installation

npm install @avatar-engine/core

Quick Start

AvatarClient (recommended)

The simplest way to connect — a batteries-included WebSocket client with auto-reconnect and state management:

import { AvatarClient } from '@avatar-engine/core'

const client = new AvatarClient('ws://localhost:8420/api/avatar/ws', {
  onStateChange(state) {
    console.log(`[${state.provider}] ${state.engineState}`)
    if (state.error) console.error(state.error)
  },
  onMessage(msg) {
    if (msg.type === 'text') process.stdout.write(msg.data.text)
    if (msg.type === 'chat_response') console.log('\n--- done ---')
  },
})

client.connect()
client.sendChat('Hello, what can you do?')

Vue 3 composable

import { reactive, onMounted, onUnmounted } from 'vue'
import { AvatarClient, type AvatarState } from '@avatar-engine/core'

export function useAvatar(url: string) {
  const state = reactive<AvatarState>({} as AvatarState)
  const client = new AvatarClient(url, {
    onStateChange: (s) => Object.assign(state, s),
  })

  onMounted(() => client.connect())
  onUnmounted(() => client.disconnect())

  return { state, client }
}

Svelte store

import { writable } from 'svelte/store'
import { AvatarClient, initialAvatarState } from '@avatar-engine/core'

export function createAvatarStore(url: string) {
  const state = writable(initialAvatarState)
  const client = new AvatarClient(url, {
    onStateChange: (s) => state.set({ ...s }),
  })

  client.connect()
  return { state, client }
}

Low-level: reducer + message builders

For full control, use the pure-function state machine directly:

import {
  avatarReducer,
  initialAvatarState,
  parseServerMessage,
  createChatMessage,
} from '@avatar-engine/core'

let state = initialAvatarState

const ws = new WebSocket('ws://localhost:8420/api/avatar/ws')

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data)
  const { action } = parseServerMessage(msg)
  if (action) {
    state = avatarReducer(state, action)
    console.log('New state:', state.engineState)
  }
}

ws.onopen = () => {
  ws.send(createChatMessage('Hello!'))
}

API Reference

AvatarClient

High-level WebSocket client with auto-reconnect.

| Method | Description | |--------|-------------| | connect() | Connect to the WebSocket server | | disconnect() | Disconnect and stop reconnecting | | getState() | Get current AvatarState snapshot | | sendChat(text, attachments?) | Send a chat message | | stop() | Cancel the current response | | switchProvider(provider, model?, options?) | Switch AI provider/model | | resumeSession(sessionId) | Resume a previous session | | newSession() | Start a new session | | sendPermissionResponse(requestId, optionId, cancelled) | Respond to a permission request | | clearHistory() | Clear conversation history |

State Machine

| Export | Description | |--------|-------------| | avatarReducer(state, action) | Pure reducer: AvatarState + AvatarActionAvatarState | | parseServerMessage(msg) | Parse a ServerMessage into an AvatarAction | | initialAvatarState | Default state (disconnected, idle) |

Message Builders

| Function | Description | |----------|-------------| | createChatMessage(text, attachments?) | Build a chat request JSON string | | createStopMessage() | Build a stop request | | createSwitchMessage(provider, model?, options?) | Build a provider switch request | | createPermissionResponse(requestId, optionId, cancelled) | Build a permission response | | createResumeSessionMessage(sessionId) | Build a session resume request | | createNewSessionMessage() | Build a new session request | | createClearHistoryMessage() | Build a clear history request |

Configuration

| Export | Description | |--------|-------------| | PROVIDERS | Default provider configurations (Gemini, Claude, Codex) | | AVATARS | Default avatar visual configurations | | buildOptionsDict(providerId, values) | Convert flat key-value options to nested provider options | | getModelDisplayName(providerId, model) | Get display name for a model | | isImageModel(model) | Check if a model supports image generation |

i18n

| Export | Description | |--------|-------------| | initAvatarI18n(reactModule?) | Initialize i18n (call before rendering) | | changeLanguage(lang) | Switch language ('en', 'cs') | | getCurrentLanguage() | Get current language code | | AVAILABLE_LANGUAGES | Supported language list |

Types

All TypeScript types for the WebSocket protocol are exported:

State types: AvatarState, EngineState, BridgeState, SafetyMode, ThinkingPhase

Server messages: ServerMessage, ConnectedMessage, TextMessage, ThinkingMessage, ToolMessage, CostMessage, ErrorMessage, ChatResponseMessage, PermissionRequestMessage, ...

Client messages: ClientMessage, ChatRequest, SwitchRequest, PermissionResponseRequest, ...

UI state: ChatMessage, ToolInfo, ThinkingInfo, CostInfo, UploadedFile, SessionInfo

Widget types: WidgetMode, BustState, AvatarConfig, AvatarPoses, PermissionRequest

Provider config: ProviderConfig, ProviderOption, ProviderCapabilities

Backend

This package is the frontend client for Avatar Engine — a Python backend that wraps Gemini CLI, Claude Code, and Codex CLI into a unified WebSocket API. See the main README for backend setup.

License

Apache-2.0