Skip to content

Commit

Permalink
fix(examples/inline-messages): deduplicate requests (#637)
Browse files Browse the repository at this point in the history
fixes #629
  • Loading branch information
Yonom authored Aug 4, 2024
1 parent da7c560 commit da8b812
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -1,64 +1,89 @@
import React, { FC, PropsWithChildren, useState, useEffect, useCallback } from "react";
import React, {
FC,
PropsWithChildren,
useState,
useEffect,
useCallback,
useRef,
} from "react";
import { Button } from "@/components/ui/button";
import { ThreadPrimitive } from "@assistant-ui/react";
import { useLastAssistantMessage } from "./LastMessageHook";
import { generate } from './actions';
import { readStreamableValue } from 'ai/rsc';
import { generate } from "./actions";
import { readStreamableValue } from "ai/rsc";

const AI_ThreadSuggestion: FC<PropsWithChildren<{}>> = ({ children }) => {
const lastAssistantMessage = useLastAssistantMessage();
const [output, setOutput] = useState<string | null>(null);
const [output2, setOutput2] = useState<string | null>(null);

const handleClick = useCallback(async () => {
const lastMessageContent = lastAssistantMessage?.content;
const lastMessageString = JSON.stringify(lastMessageContent);
console.log('LM:', lastMessageString);
const debounceRef = useRef(false);
const generateSuggestions = useCallback(async (content: string) => {
// do not send duplicate requests in React Strict Mode during development
if (process.env.NODE_ENV === "development") {
if (debounceRef.current) return;
debounceRef.current = true;
setTimeout(() => {
debounceRef.current = false;
}, 0);
}

const [response1, response2] = await Promise.all([
generate(`Generate a optimistic very very short one sentence follow up question based on this response: ${lastMessageString}`),
generate(`Generate a very skeptical very very short one sentence follow up question based on this response: ${lastMessageString}`)
generate(
`Generate a optimistic very very short one sentence follow up question based on this response: "${content}"`,
),
generate(
`Generate a very skeptical very very short one sentence follow up question based on this response: "${content}"`,
),
]);

let generatedOutput = '';
let generatedOutput = "";
for await (const delta of readStreamableValue(response1.output)) {
generatedOutput += delta;
}
console.log(generatedOutput);
setOutput(generatedOutput);

let generatedOutput2 = '';
let generatedOutput2 = "";
for await (const delta of readStreamableValue(response2.output)) {
generatedOutput2 += delta;
}
console.log(generatedOutput2);
setOutput2(generatedOutput2);
}, [lastAssistantMessage]);
}, []);

useEffect(() => {
if (lastAssistantMessage) {
handleClick();
}
}, [lastAssistantMessage, handleClick]);
const lastMessageContent = lastAssistantMessage?.content;
const lastMessageString = JSON.stringify(lastMessageContent);
generateSuggestions(lastMessageString);
}, [lastAssistantMessage, generateSuggestions]);

return (
<div className="flex w-full space-x-2">
<ThreadPrimitive.Suggestion prompt={output || ''} method="replace" autoSend asChild>
<ThreadPrimitive.Suggestion
prompt={output || ""}
method="replace"
autoSend
asChild
>
<Button
variant="outline"
className="flex-1 h-auto p-2"
onClick={handleClick}
style={{ whiteSpace: 'normal', wordWrap: 'break-word' }}
className="h-auto flex-1 p-2"
style={{ whiteSpace: "normal", wordWrap: "break-word" }}
>
{output || children}
</Button>
</ThreadPrimitive.Suggestion>
<ThreadPrimitive.Suggestion prompt={output2 || ''} method="replace" autoSend asChild>
<ThreadPrimitive.Suggestion
prompt={output2 || ""}
method="replace"
autoSend
asChild
>
<Button
variant="outline"
className="flex-1 h-auto p-2"
onClick={handleClick}
style={{ whiteSpace: 'normal', wordWrap: 'break-word' }}
className="h-auto flex-1 p-2"
style={{ whiteSpace: "normal", wordWrap: "break-word" }}
>
{output2 || children}
</Button>
Expand All @@ -67,4 +92,12 @@ const AI_ThreadSuggestion: FC<PropsWithChildren<{}>> = ({ children }) => {
);
};

export default AI_ThreadSuggestion;
const WrappedAI_ThreadSuggestion = () => {
return (
<ThreadPrimitive.If running={false}>
<AI_ThreadSuggestion />
</ThreadPrimitive.If>
);
};

export default WrappedAI_ThreadSuggestion;
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { ThreadAssistantMessage } from "@assistant-ui/react";
import { useThreadContext } from "@assistant-ui/react";
import { useMemo } from "react";

export const useLastAssistantMessage = () => {
const { useThreadMessages } = useThreadContext();
const messages = useThreadMessages();

return useMemo(() => {
return useThreadMessages((messages) => {
for (let i = messages.length - 1; i >= 0; i--) {
if (messages[i].role === "assistant") {
return messages[i];
if (messages[i]?.role === "assistant") {
return messages[i]! as ThreadAssistantMessage;
}
}
return null;
}, [messages]);
};
});
};

0 comments on commit da8b812

Please sign in to comment.