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

@arraylee/folotoy-debate-plugin

v0.1.5

Published

FoloToy multi-device debate & performance plugin for OpenClaw

Readme

@folotoy/folotoy-openclaw-plugin

Empower your FoloToy with OpenClaw AI capabilities.

An OpenClaw channel plugin that bridges FoloToy smart toys with OpenClaw via MQTT.

FoloToy Toy  <──MQTT──>  FoloToy MQTT Broker  <──MQTT──>  Plugin  <──>  OpenClaw

Installation

openclaw plugins install @folotoy/folotoy-openclaw-plugin

For local development:

openclaw plugins install -l .

Configuration

The plugin supports two authentication flows. All fields are configured as flat key-value pairs in openclaw.json under channels.folotoy.

Flow 2: Direct SN + Key (Default)

| Field | Description | |-------|-------------| | flow | "direct" | | toy_sn | Toy serial number | | toy_key | Toy key (used as MQTT password) | | mqtt_host | MQTT broker host (default: 198.19.249.25) | | mqtt_port | MQTT broker port (default: 1883) | | summary_enabled | Enable reply summarization (default: true) | | summary_max_chars | Character threshold for summarization (default: 200) |

Flow 1: HTTP API Login

Exchange an API key for MQTT credentials via the FoloToy API:

| Field | Description | |-------|-------------| | flow | "api" | | toy_sn | Toy serial number | | api_url | FoloToy API base URL (default: https://api.folotoy.cn) | | api_key | Bearer token | | mqtt_host | MQTT broker host | | mqtt_port | MQTT broker port (default: 1883) |

Example openclaw.json:

{
  "channels": {
    "folotoy": {
      "flow": "direct",
      "toy_sn": "your-toy-sn",
      "toy_key": "your-toy-key",
      "mqtt_host": "198.19.249.25",
      "summary_enabled": true,
      "summary_max_chars": 200
    }
  }
}

MQTT

Inbound and outbound use separate topics:

Inbound  (Toy → Plugin):  /openapi/folotoy/{sn}/thing/command/call
Outbound (Plugin → Toy):  /openapi/folotoy/{sn}/thing/command/callAck

The plugin connects with an openapi: prefix on the clientId to distinguish itself from the toy's own connection:

clientId: openapi:{toy_sn}
username: {toy_sn}
password: {toy_key}

Connection failures trigger exponential backoff reconnection (1s → 2s → 4s → ... → 60s max), resetting on successful connect.

Message Format

Toy → Plugin (inbound)

{
  "msgId": 1,
  "identifier": "chat_input",
  "inputParams": {
    "text": "hello",
    "recording_id": 100
  }
}

Plugin → Toy (outbound)

Reply is buffered, then summarized if it exceeds summary_max_chars. Sent as a single message with auto-incrementing order, followed by a finish message:

{
  "msgId": 1,
  "identifier": "chat_output",
  "outParams": {
    "content": "hello",
    "recording_id": 100,
    "order": 1,
    "is_finished": false
  }
}

Finish message (is_finished: true, empty content):

{
  "msgId": 1,
  "identifier": "chat_output",
  "outParams": {
    "content": "",
    "recording_id": 100,
    "order": 2,
    "is_finished": true
  }
}

msgId starts at 1 per session and auto-increments. recording_id is passed through from the inbound message.

Environments

| Environment | MQTT Host | Port | |-------------|-----------|------| | Development | 198.19.249.25 | 1883 | | Testing | f.qrc92.cn | 1883 | | Production | f.folotoy.cn | 1883 |

Switch environments via the FOLOTOY_MQTT_HOST environment variable or mqtt_host config field.

Features

Reply Summarization

When AI reply exceeds summary_max_chars (default 200), the plugin uses the primary model to generate a concise summary before sending to the toy. This avoids excessively long voice playback. Falls back to truncation on failure. Disable with summary_enabled: false.

Soothing Acknowledgment

Immediately sends a transitional reply (e.g., "Let me think...") upon receiving a message, providing instant feedback while the AI processes.

Exponential Backoff Reconnection

MQTT connection failures trigger automatic reconnection with exponential backoff (1s → 60s cap), resetting on success.

Development

pnpm install
pnpm test
pnpm build

License

MIT