ai icon indicating copy to clipboard operation
ai copied to clipboard

Add new field `isPending` in useChat

Open himself65 opened this issue 1 year ago • 6 comments

Feature Description

isLoading is not enough for some products since its lifecycle is during the whole text streaming.

As shown in the figure, I hope there is a new field called isPending to show that the server is processing the request and false once after the streaming has started. image

Use Case

my downstream PR that fakes a isPending field using useDeferredValue.

https://github.com/run-llama/LlamaIndexTS/pull/203

const content = lastMessage?.content ?? "";
const deferredContent = useDeferredValue(content);
const isPending = props.isLoading ? !isLastMessageFromAssistant : (
  props.isLoading &&
  isLastMessageFromAssistant && content === deferredContent
);

Additional context

No response

himself65 avatar Nov 18 '23 04:11 himself65

isPending = waiting IsLoading = responding

tgonzales avatar Nov 18 '23 08:11 tgonzales

isPending = waiting IsLoading = responding

Yeah, that's true

himself65 avatar Nov 18 '23 09:11 himself65

Was just strugging to implement this a few days ago, would love to see this added as well 👍

chanmathew avatar Nov 25 '23 04:11 chanmathew

better solution:

// `isPending` indicate
// that stream response is not yet received from the server,
// so we show a loading indicator to give a better UX.
const isPending = props.isLoading && !isLastMessageFromAssistant;

himself65 avatar Nov 25 '23 08:11 himself65

I'm doing the following:

const { messages, handleInputChange, handleSubmit } = useChat();

...

// for displaying loading icon before stream response is received
useEffect(() => {
  if (messages.length % 2 === 1) {
    setPending(true);
  } else {
    setPending(false);
  }
}, [messages]);

I believe it works assuming there's always a user message in between every streamed message. If the agent is going to speak first in the conversation, then you could use messages.length % 2 === 0 in the useEffect instead. Obviously it's just a workaround until the library provides a solution.

j-d90 avatar Dec 26 '23 11:12 j-d90

I am late to reply, but here is my iteration:

  const isPending = useMemo(() => messages.length % 2 === 1, [messages])

trulymittal avatar Feb 26 '24 13:02 trulymittal

the isPending calculation is problematic because sometimes the AI returns more than one message so the division by 2 goes out of whack. Anyone found a better way ?

ghoshsanjoy78 avatar Aug 16 '24 06:08 ghoshsanjoy78

@ghoshsanjoy78 you can check if all of the following are true: isLoading, last message is assistant message, last message has some content (text, tool call -- text will prob be enough for most use cases)

lgrammel avatar Aug 16 '24 06:08 lgrammel

Thanks @lgrammel but checking if isLoading is true does not help since isLoading remains true during the entire duration of streaming. What I want to do is show a "..." thinking bubble while the tool calls are being made but once the response starts streaming, want to remove the "..." bubble. isLoading does not help with this since it remains true for the entire duration of stream.

The original diagram from @himself65 explained this best - streaming

ghoshsanjoy78 avatar Aug 16 '24 06:08 ghoshsanjoy78

sorry there was a typo in my msg, here is what i meant

you can check if ALL of the following are true:

  • isLoading is true
  • last message is an assistant message
  • last message has DOES NOT have content

lgrammel avatar Aug 16 '24 06:08 lgrammel

Yes - that worked! Thanks!

ghoshsanjoy78 avatar Aug 16 '24 06:08 ghoshsanjoy78