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

bot-chat-manager

v1.0.16

Published

frontend state manager for AI bot chat, providing React hooks and state store | 前端 AI 对话状态管理工具

Readme

Bot Chat Manager

npm version License: MIT

English

前端 AI 机器人聊天状态管理器,用于管理 AI 对话界面的数据状态并驱动对话组件渲染,提供以下两种使用方式:

  • React Hooks
  • 状态管理 store

特性

  • 🔄 通用的对话状态管理
  • 🪝 便捷的 React Hooks 集成
  • 🧩 通过自定义命令驱动,具备高扩展性、低耦合度
  • 📝 完备的 Typescript 类型声明
  • 🧰 灵活的消息气泡数据结构(支持 ts 泛型)

安装

npm install bot-chat-manager
# 或
yarn add bot-chat-manager

基本使用:React Hooks

import React, { useState } from 'react';
import useBotChat, { Command } from 'bot-chat-manager';

// 自定义命令:发送用户消息并接收机器人回复
const commandSendQuery = (userInput: string): Command => 
  async chatCtx => {
      // 标记新一轮对话开始,此后所有消息都将被视为一轮对话,直到执行下一个 toggleChatRound (手动给消息列表划分轮次,便于实现某些功能,比如撤销最后一轮对话)
      chatCtx.toggleChatRound();
      // 添加用户气泡消息
      chatCtx.addUserBubble(userInput);
      // 添加机器人加载气泡消息,并获得其气泡 id
      const loadingId = chatCtx.addBotLoadingBubble();
      let loadingContent = '';

      // 发送请求并处理 SSE 响应
      const onSSEChunk = chunk => {
        loadingContent += chunk.content;
        chatCtx.updateBubble(loadingId, {
          content: loadingContent, // 追加 SSE 响应内容
          sugs: chunk.suggestions || [], // SSE 响应建议(bot-chat-manager 会自动判断是否应该展示该 sugs)
          status: 'incomplete', // SSE 未结束,机器人气泡状态为未完成
        });
      };
      const onCloseSSE = () => {
        chatCtx.updateBubble(loadingId, { // SSE 结束,将机器人气泡状态设置为完成
          status: 'complete',
        });
      };
      const onSSEError = () => {
        chatCtx.updateBubble(loadingId, { // SSE 错误,将机器人气泡状态设置为错误
          status: 'error',
        });
      };
      const request = genRequest(userInput);
      await fetchBotResponseBySSE(request, onSSEChunk, onCloseSSE, onSSEError);
  };

const ChatComponent = () => {
  
  // 聊天管理器
  const { 
    bubbles,           // 当前所有消息气泡状态,包含消息内容、建议回复、状态等
    sugs,              // 当前需要显示的 sugs
    execute,           // 执行自定义命令,驱动 bubbles 更新
    COMMAND_CLEAR_ALL, // 内置命令:清空所有消息
    COMMAND_WITHDRAW_LAST_ROUND // 内置命令:撤回最后一轮对话
  } = useBotChat('bot', 'user'); // 指定机器人与用户的角色标识
  
  // 发送消息示例
  const handleSend = async (userInput: string) => {
    await execute(commandSendQuery(userInput)); // 执行命令:发起对话
  };

  // 撤回最后一轮对话
  const handleWithdraw = () => {
    execute(COMMAND_WITHDRAW_LAST_ROUND);
  };

  const messages = convert2UIMessages(bubbles);
  
  return (
    <div className="chat-container">
      <div className="chat-box">
        <BotChat messages={messages} sugs={sugs} onWithdraw={handleWithdraw} />
      </div>
      <div className="input-area">
        <UserInput
          onSend={handleSend}
          placeholder="输入消息..."
        />
      </div>
    </div>
  );
};

export default ChatComponent;

基本使用:状态管理 store

如果您的项目不适合使用 React Hooks,可以直接使用BotChatState class 来生成 store 实例,然后在组件中使用该实例来管理聊天状态

import { BotChatState } from 'bot-chat-manager';

const chatState = new BotChatState('bot', 'user', []);  // 指定机器人与用户的角色标识, 并(可选)初始化消息列表(空)

const ChatComponent = () => {
  const [messages, setMessages] = useState<MessageInfo[]>([]);
  const [sugs, setSugs] = useState<string[]>([]);

  useEffect(() => {
    const unsubscribe = chatState.subscribe(({ bubbles, sugs }) => {
      const messages = convert2UIMessages(bubbles);
      setMessages(messages);
      setSugs(sugs);
    });
    return () => {
      unsubscribe();
    };
  }, []);
  
  // 发送消息示例
  const handleSend = async (userInput: string) => {
    await chatState.execute(commandSendQuery(userInput)); // 执行命令:发起对话
  };

  // 撤回最后一轮对话
  const handleWithdraw = () => {
    chatState.execute(COMMAND_WITHDRAW_LAST_ROUND);
  };

  
  return (
    <div className="chat-container">
      <div className="chat-box">
        <BotChat messages={messages} sugs={sugs} onWithdraw={handleWithdraw} />
      </div>
      <div className="input-area">
        <UserInput
          onSend={handleSend}
          placeholder="输入消息..."
        />
      </div>
    </div>
  );
};

进阶用法: 自定义消息气泡类型

您可以扩展默认的消息气泡类型 BubbleInfo,添加自定义字段,并将新的类型用作泛型参数:

import useBotChat, { BubbleInfo } from 'bot-chat-manager';

// 扩展气泡类型
interface CustomBubble extends BubbleInfo {
  isHighlighted?: boolean;
  attachments?: string[];
}

const ChatComponent = () => {

  // 使用自定义类型
  const { bubbles, sugs, execute } = useBotChat<CustomBubble>('bot', 'user');

  // 自定义命令:添加一条用户附件消息
  const commandAddUserAttachmentMessage = (userInput: string, files: string[]): Command => 
    chatCtx => {
      chatCtx.addUserBubble(userInput, {
        isHighlighted: true,
        attachments: files, // ['file1.pdf', 'image.jpg']
      });
    };

  // 发送消息示例
  const handleSendMulti = async (userInput: string, files: string[]) => {
    await execute(commandAddUserAttachmentMessage(userInput, files));
  };

  const messages = convert2UIMessages(bubbles);

  return (
    <div className="chat-container">
      <div className="chat-box">
        <BotChat messages={messages} sugs={sugs} />
      </div>
      <div className="input-area">
        <UserInput
          onSendMulti={handleSendMulti}
          placeholder="输入消息..."
        />
      </div>
    </div>
  );
}

类型定义

useBotChat

useBotChat<M extends BubbleInfo = BubbleInfo>(botRole: string, userRole: string, initialBubbles?: M[])

参数

  • botRole: 机器人角色标识
  • userRole: 用户角色标识
  • initialBubbles: 可选的初始气泡数组

返回值

  • bubbles: 当前所有消息气泡数组
  • sugs: 当前建议回复数组
  • execute: 执行命令的函数
  • COMMAND_WITHDRAW_LAST_ROUND: 内置命令,撤回最后一轮对话
  • COMMAND_CLEAR_ALL: 内置命令,清空所有消息

BubbleInfo

interface BubbleInfo {
  id?: string;           // 消息气泡的唯一标识
  role: string;          // 发送当前消息气泡的角色
  content: string;       // 消息气泡的内容
  ts?: number;     // 时间戳(毫秒)
  status?: BubbleStatus; // 消息气泡的状态
  roundId?: string;      // 用于标识一轮对话
  sugs?: string[];       // 消息气泡的建议回复列表
  [x: string]: any;      // 其他自定义字段
}

type BubbleStatus = 'loading' | 'incomplete' | 'complete' | 'error';

Command

type Command<M extends BubbleInfo = BubbleInfo> = (chatCtx: ChatCtx<M>) => void | Promise<void>;

ChatCtx

interface ChatCtx<M extends BubbleInfo = BubbleInfo> {
  // 查询方法
  getCurrentBubbles: () => M[];
  getCurrentSugs: () => string[];
  getBubble: (id: string) => M | undefined;
  
  // 删除方法
  deleteBubble: (id: string) => void;
  clearBubbles: () => void;
  withdrawLastRound: () => void;
  
  // 更新方法
  setBubbles: (bubbles: M[]) => void;
  updateBubble: (id: string, props: Partial<M>) => void;
  toggleChatRound: () => string;
  
  // 添加方法
  addUserBubble: (content: string, props?: Partial<M>) => string;
  addBotBubble: (content: string, props?: Partial<M>) => string;
  addBotLoadingBubble: (props?: Partial<M>) => string;
}

许可证

MIT