Skip to content

希望useXChat能提供onUpdate和onSuccess时的事件监听函数 #812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
hlwz5735 opened this issue May 9, 2025 · 3 comments
Open
Labels
enhancement New feature or request

Comments

@hlwz5735
Copy link

hlwz5735 commented May 9, 2025

需求动机

我在尝试接入自定义的LLM聊天接口,这个接口会在不传入对话ID时,在第一条SSE响应中返回服务端创建的会话ID。我希望在服务端推过来对话ID时,在左侧对话列表中创建一个新项。

我定义了一个带有自定义 request 的 XAgent,传给了 useXChat。但是现在的 useXChat 好像没有提供收到SSE响应或SSE推送完成时做出反应的API。

我现在用的一个折中的方案是自定义一个消息的 parser,在 parser 中执行一些副作用行为:

  const { onRequest, messages, parsedMessages, setMessages } = useXChat({
    agent,
    requestPlaceholder: { answer: '深度思考中...' },
    requestFallback: { answer: '接口调用失败,请联系管理员或稍候再试。' },
    parser: (difyMsg: DifyAssistMessage) => {
      if (difyMsg.conversationId && !activeKeyRef.current) {
        console.log(
          `创建会话信息!${activeKeyRef.current} -> ${difyMsg.conversationId}`,
        );
        addConversation(difyMsg.conversationId);
      }
      return difyMsg.answer;
    },
  });

但是 parser 会在消息列表发生更新时,对所有 messages 条目进行处理,而且在一个解析消息体的方法中执行副作用,总感觉怪怪的。

另一个方案是在发送之前先判断一下是否要新建会话,如果是的话先新建一个假会话,然后在 XAgent 的自定义 request 中,等响应完成后再借助状态管理库更新假会话的ID为真ID。这个方案也有问题,比如当会话正在往外吐输出的时候再新建一个会话,旧的会话如果没有妥善取消,有可能会导致在新的会话界面执行了旧的会话回调,把整个会话ID给搞乱掉。

我还能想到的一个方法是在 onRequest 的时候,自定义两个回调函数作为 RequestParams 成员传进去,然后在自定义 request 方法中,调用 onUpdate 和 onSuccess 回调的同时分别执行这两个回调。不确定这种方式是不是会有闭包问题,或许还得再用 useRef 裹一层?

提议的 API 是什么样的?

我觉得可能大概率咱们现在的功能是可以实现我的需求的,是我认识浅薄没找到最佳的实践方式。如果是我的思路不对,也请各位直接指正。

希望 useXChat 能提供 onUpdate 和 onSuccess 的回调函数,可以放在 useXChat 中,或在调用 onRequest 时动态传入。

即:

  const { onRequest, messages, parsedMessages, setMessages } = useXChat({
    agent,
    onMessageChunkUpdate: (msg, messages) => { // 当服务端推来新的消息分块时,外界可以做出反应 },
    onMessagePushingDone: (msg, messages) => { // 当服务端消息推送完成时,外界可以做出反应 },
  });

或者:

  const onSubmit = (nextContent: string) => {
    if (!nextContent) {
      return;
    }
    onRequest({
      message: { answer: nextContent },
      conversationId: activeConversationKey,
    }, {
      onMessageChunkUpdate: (msg, messages) => { // 当服务端推来新的消息分块时,外界可以做出反应 },
      onMessagePushingDone: (msg, messages) => { // 当服务端消息推送完成时,外界可以做出反应 },
    });
    setContent('');
  };
Copy link

感谢您分享您的需求和想法。您希望 useXChat 能提供 onUpdateonSuccess 的事件监听函数,以便在接收到服务端推送的对话ID时,能够在左侧对话列表中创建一个新项。

您的提议是希望 useXChat 能够提供类似以下的API:

  1. useXChat 中直接传入回调函数:

    const { onRequest, messages, parsedMessages, setMessages } = useXChat({
      agent,
      onMessageChunkUpdate: (msg, messages) => { /* 当服务端推来新的消息分块时,外界可以做出反应 */ },
      onMessagePushingDone: (msg, messages) => { /* 当服务端消息推送完成时,外界可以做出反应 */ },
    });
  2. 在调用 onRequest 时动态传入回调函数:

    const onSubmit = (nextContent: string) => {
      if (!nextContent) {
        return;
      }
      onRequest({
        message: { answer: nextContent },
        conversationId: activeConversationKey,
      }, {
        onMessageChunkUpdate: (msg, messages) => { /* 当服务端推来新的消息分块时,外界可以做出反应 */ },
        onMessagePushingDone: (msg, messages) => { /* 当服务端消息推送完成时,外界可以做出反应 */ },
      });
      setContent('');
    };

这种设计可以让开发者在特定事件发生时执行自定义逻辑,而不需要在 parser 中执行副作用,避免了代码的复杂性和潜在的闭包问题。

如果您同意,我可以为您创建一个功能请求,以便开发团队能够考虑将此功能添加到 useXChat 中。请确认是否需要我为您提交此请求。

🪧 Tips For further assistance, please describe your question in the comments and @petercat-assistant to start a conversation with me.

@dosubot dosubot bot added the enhancement New feature or request label May 9, 2025
@jitianxiang
Copy link

XAgent里读stream流的时候顺带更新conversationId不就行了

@hlwz5735
Copy link
Author

hlwz5735 commented May 9, 2025

XAgent里读stream流的时候顺带更新conversationId不就行了

考虑到可能会在不同的场合下复用请求的逻辑,我把自定义的request方法实现写在了单独的ts文件里了,不在组件里,所以没办法直接更新组件的状态……

虽然用状态管理库可以在组件之外更新状态,但是还是考虑到一旦这样做,基本上这个request方法就和使用了相关状态的页面组件高度耦合了,还是没区别……

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants