44 ChatBOSResponse ,
55 ChatDeltaResponse ,
66 MessageStatus ,
7+ OpenAIMessageRole ,
78} from '@/page/chat/types/chat-response' ;
89import {
910 ConversationDetail ,
@@ -19,9 +20,48 @@ export interface MessageOperator {
1920 add : ( chatResponse : ChatBOSResponse ) => string ;
2021 done : ( id ?: string ) => void ;
2122 activate : ( id : string ) => void ;
23+ getSiblings : ( id : string ) => string [ ] ;
24+ getParent : ( id : string ) => string ;
25+ }
26+
27+ function getChildren (
28+ conversation : ConversationDetail ,
29+ id : string ,
30+ targetRole : OpenAIMessageRole
31+ ) : string [ ] {
32+ if ( targetRole === OpenAIMessageRole . ASSISTANT ) {
33+ const currentNode = conversation . mapping [ id ] ;
34+ if ( currentNode ) {
35+ if (
36+ currentNode . message . role === OpenAIMessageRole . ASSISTANT &&
37+ ! currentNode . message . tool_calls
38+ ) {
39+ return [ id ] ;
40+ }
41+ const targetChildren : string [ ] = [ ] ;
42+ for ( const childId of currentNode . children || [ ] ) {
43+ targetChildren . push ( ...getChildren ( conversation , childId , targetRole ) ) ;
44+ }
45+ return targetChildren ;
46+ }
47+ } else if ( targetRole === OpenAIMessageRole . USER ) {
48+ const currentNode = conversation . mapping [ id ] ;
49+ if ( currentNode ) {
50+ return currentNode . children ;
51+ }
52+ const children : string [ ] = [ ] ;
53+ for ( const node of Object . values ( conversation . mapping ) ) {
54+ if ( node . parent_id === id ) {
55+ children . push ( node . id ) ;
56+ }
57+ }
58+ return children ;
59+ }
60+ return [ ] ;
2261}
2362
2463export function createMessageOperator (
64+ conversation : ConversationDetail ,
2565 setConversation : Dispatch < SetStateAction < ConversationDetail > >
2666) : MessageOperator {
2767 return {
@@ -82,11 +122,8 @@ export function createMessageOperator(
82122
83123 setConversation ( prev => {
84124 const newMapping = { ...prev . mapping , [ message . id ] : message } ;
85- let currentNode = prev . current_node ;
86- if ( message . parent_id === currentNode ) {
87- currentNode = message . id ;
88- }
89- if ( message . parent_id ) {
125+
126+ if ( message . parent_id && prev . current_node !== undefined ) {
90127 const parentMessage = prev . mapping [ message . parent_id ] ;
91128 if ( parentMessage ) {
92129 if ( ! parentMessage . children . includes ( message . id ) ) {
@@ -101,7 +138,7 @@ export function createMessageOperator(
101138 return {
102139 ...prev ,
103140 mapping : newMapping ,
104- current_node : currentNode ,
141+ current_node : message . id ,
105142 } ;
106143 } ) ;
107144 return chatResponse . id ;
@@ -124,9 +161,50 @@ export function createMessageOperator(
124161 } ) ;
125162 } ,
126163
164+ /**
165+ * Get siblings of a message.
166+ * @param id
167+ */
168+ getSiblings : ( id : string ) : string [ ] => {
169+ const currentNode = conversation . mapping [ id ] ;
170+ if ( currentNode . message . tool_calls ) {
171+ return [ id ] ;
172+ }
173+ if ( currentNode ) {
174+ const currentRole = currentNode . message . role ;
175+ if ( currentNode . message . role === OpenAIMessageRole . USER ) {
176+ return getChildren ( conversation , currentNode . parent_id , currentRole ) ;
177+ }
178+ let parentNode = currentNode ;
179+ while ( parentNode . message . role !== OpenAIMessageRole . USER ) {
180+ parentNode = conversation . mapping [ parentNode . parent_id ] ;
181+ }
182+ return getChildren ( conversation , parentNode . id , currentRole ) ;
183+ }
184+ return [ ] ;
185+ } ,
186+
187+ /**
188+ * Get non-tool parent of a message.
189+ * @param id
190+ */
191+ getParent : ( id : string ) : string => {
192+ let currentNode = conversation . mapping [ id ] ;
193+ if ( currentNode ) {
194+ const targetRoles =
195+ currentNode . message . role === OpenAIMessageRole . ASSISTANT
196+ ? [ OpenAIMessageRole . USER ]
197+ : [ OpenAIMessageRole . ASSISTANT , OpenAIMessageRole . SYSTEM ] ;
198+ while ( ! targetRoles . includes ( currentNode . message . role ) ) {
199+ currentNode = conversation . mapping [ currentNode . parent_id ] ;
200+ }
201+ return currentNode . id ;
202+ }
203+ return '' ;
204+ } ,
205+
127206 /**
128207 * When there is multi message, activate one of them.
129- * Designed for future, now enabled for now.
130208 * @param id
131209 */
132210 activate : ( id : string ) => {
0 commit comments