Skip to content

Commit 0dc85d4

Browse files
committed
add edit functionality
1 parent b820f8e commit 0dc85d4

File tree

1 file changed

+91
-17
lines changed

1 file changed

+91
-17
lines changed

client/packages/lowcoder/src/comps/comps/chatComp/components/context/MyRuntimeProvider.tsx

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ import {
66
AssistantRuntimeProvider,
77
} from "@assistant-ui/react";
88

9+
// Define your custom message type
10+
interface MyMessage {
11+
id: string;
12+
role: "user" | "assistant";
13+
text: string;
14+
timestamp: number;
15+
}
16+
17+
const generateId = () => Math.random().toString(36).substr(2, 9);
18+
919
const callYourAPI = async (message: AppendMessage) => {
1020
// Simulate API delay
1121
await new Promise(resolve => setTimeout(resolve, 1500));
@@ -15,56 +25,120 @@ const callYourAPI = async (message: AppendMessage) => {
1525
content: "This is a mock response from your backend. You typed: " +
1626
(typeof message.content === 'string' ? message.content : 'something')
1727
};
18-
};
28+
};
1929

2030
export function MyRuntimeProvider({ children }: { children: React.ReactNode }) {
21-
const [messages, setMessages] = useState<ThreadMessageLike[]>([]);
31+
// Use your custom message type in state
32+
const [myMessages, setMyMessages] = useState<MyMessage[]>([]);
2233
const [isRunning, setIsRunning] = useState(false);
34+
35+
// Convert your custom format to ThreadMessageLike
36+
const convertMessage = (message: MyMessage): ThreadMessageLike => ({
37+
role: message.role,
38+
content: [{ type: "text", text: message.text }],
39+
id: message.id,
40+
createdAt: new Date(message.timestamp),
41+
});
2342

2443
const onNew = async (message: AppendMessage) => {
25-
// Add user message
26-
const userMessage: ThreadMessageLike = {
44+
// Add user message in your custom format
45+
const userMessage: MyMessage = {
46+
id: generateId(),
2747
role: "user",
28-
content: message.content,
48+
text: typeof message.content === 'string' ? message.content : JSON.stringify(message.content),
49+
timestamp: Date.now(),
2950
};
3051

31-
setMessages(prev => [...prev, userMessage]);
52+
setMyMessages(prev => [...prev, userMessage]);
3253
setIsRunning(true);
3354

3455
try {
3556
// Call mock API
3657
const response = await callYourAPI(message);
3758

38-
const assistantMessage: ThreadMessageLike = {
59+
const assistantMessage: MyMessage = {
60+
id: generateId(),
61+
role: "assistant",
62+
text: response.content,
63+
timestamp: Date.now(),
64+
};
65+
66+
setMyMessages(prev => [...prev, assistantMessage]);
67+
} catch (error) {
68+
// Handle errors gracefully
69+
const errorMessage: MyMessage = {
70+
id: generateId(),
71+
role: "assistant",
72+
text: `Sorry, I encountered an error: ${error instanceof Error ? error.message : 'Unknown error'}. This is expected in mock mode for testing error handling.`,
73+
timestamp: Date.now(),
74+
};
75+
76+
setMyMessages(prev => [...prev, errorMessage]);
77+
} finally {
78+
setIsRunning(false);
79+
}
80+
};
81+
82+
// Add onEdit functionality
83+
const onEdit = async (message: AppendMessage) => {
84+
// Find the index where to insert the edited message
85+
const index = myMessages.findIndex((m) => m.id === message.parentId) + 1;
86+
87+
// Keep messages up to the parent
88+
const newMessages = [...myMessages.slice(0, index)];
89+
90+
// Add the edited message in your custom format
91+
const editedMessage: MyMessage = {
92+
id: generateId(), // Always generate new ID for edited messages
93+
role: "user",
94+
text: typeof message.content === 'string' ? message.content : JSON.stringify(message.content),
95+
timestamp: Date.now(),
96+
};
97+
newMessages.push(editedMessage);
98+
99+
setMyMessages(newMessages);
100+
setIsRunning(true);
101+
102+
try {
103+
// Generate new response
104+
const response = await callYourAPI(message);
105+
106+
const assistantMessage: MyMessage = {
107+
id: generateId(),
39108
role: "assistant",
40-
content: response.content,
109+
text: response.content,
110+
timestamp: Date.now(),
41111
};
42112

43-
setMessages(prev => [...prev, assistantMessage]);
113+
newMessages.push(assistantMessage);
114+
setMyMessages(newMessages);
44115
} catch (error) {
45116
// Handle errors gracefully
46-
const errorMessage: ThreadMessageLike = {
117+
const errorMessage: MyMessage = {
118+
id: generateId(),
47119
role: "assistant",
48-
content: `Sorry, I encountered an error: ${error instanceof Error ? error.message : 'Unknown error'}. This is expected in mock mode for testing error handling.`,
120+
text: `Sorry, I encountered an error: ${error instanceof Error ? error.message : 'Unknown error'}`,
121+
timestamp: Date.now(),
49122
};
50123

51-
setMessages(prev => [...prev, errorMessage]);
124+
newMessages.push(errorMessage);
125+
setMyMessages(newMessages);
52126
} finally {
53127
setIsRunning(false);
54128
}
55129
};
56130

57-
const runtime = useExternalStoreRuntime<ThreadMessageLike>({
58-
messages,
59-
setMessages,
131+
const runtime = useExternalStoreRuntime({
132+
messages: myMessages, // Your custom message array
133+
convertMessage, // Conversion function
60134
isRunning,
61135
onNew,
62-
convertMessage: (message) => message,
136+
onEdit, // Enable message editing
63137
});
64138

65139
return (
66140
<AssistantRuntimeProvider runtime={runtime}>
67141
{children}
68142
</AssistantRuntimeProvider>
69143
);
70-
}
144+
}

0 commit comments

Comments
 (0)