@@ -15,14 +15,22 @@ interface ResultStreamWriter {
15
15
interface FileDetailsWithPath extends FileDetails {
16
16
relativeFilePath : string
17
17
}
18
+
19
+ type OperationType = 'read' | 'write' | 'listDir'
20
+
21
+ interface FileOperation {
22
+ type : OperationType
23
+ filePaths : FileDetailsWithPath [ ]
24
+ }
18
25
export class AgenticChatResultStream {
19
26
static readonly resultDelimiter = '\n\n'
20
27
#state = {
21
28
chatResultBlocks : [ ] as ChatMessage [ ] ,
22
29
isLocked : false ,
23
- contextFileList : { } as Record < string , FileDetailsWithPath [ ] > ,
24
30
uuid : randomUUID ( ) ,
25
31
messageId : undefined as string | undefined ,
32
+ messageIdToUpdate : undefined as string | undefined ,
33
+ messageOperations : new Map < string , FileOperation > ( ) ,
26
34
}
27
35
readonly #sendProgress: ( newChatResult : ChatResult | string ) => Promise < void >
28
36
@@ -33,16 +41,31 @@ export class AgenticChatResultStream {
33
41
getResult ( only ?: string ) : ChatResult {
34
42
return this . #joinResults( this . #state. chatResultBlocks , only )
35
43
}
44
+ getMessageIdToUpdate ( ) : string | undefined {
45
+ return this . #state. messageIdToUpdate
46
+ }
36
47
37
- getContextFileList ( toolUseId : string ) : FileDetailsWithPath [ ] {
38
- return this . #state. contextFileList [ toolUseId ] ?? [ ]
48
+ setMessageIdToUpdate ( messageId : string ) {
49
+ this . #state. messageIdToUpdate = messageId
39
50
}
40
51
41
- addContextFileList ( toolUseId : string , fileDetails : FileDetailsWithPath ) {
42
- if ( ! this . #state. contextFileList [ toolUseId ] ) {
43
- this . #state. contextFileList [ toolUseId ] = [ ]
44
- }
45
- this . #state. contextFileList [ toolUseId ] . push ( fileDetails )
52
+ /**
53
+ * Adds a file operation for a specific message
54
+ * @param messageId The ID of the message
55
+ * @param type The type of operation ('read' or 'listDir' or 'write')
56
+ * @param filePaths Array of FileDetailsWithPath involved in the operation
57
+ */
58
+ addMessageOperation ( messageId : string , type : OperationType , filePaths : FileDetailsWithPath [ ] ) {
59
+ this . #state. messageOperations . set ( messageId , { type, filePaths } )
60
+ }
61
+
62
+ /**
63
+ * Gets the file operation details for a specific message
64
+ * @param messageId The ID of the message
65
+ * @returns The file operation details or undefined if not found
66
+ */
67
+ getMessageOperation ( messageId : string ) : FileOperation | undefined {
68
+ return this . #state. messageOperations . get ( messageId )
46
69
}
47
70
48
71
#joinResults( chatResults : ChatMessage [ ] , only ?: string ) : ChatResult {
@@ -74,17 +97,18 @@ export class AgenticChatResultStream {
74
97
am . messageId === c . messageId
75
98
? am . body + AgenticChatResultStream . resultDelimiter + c . body
76
99
: am . body ,
77
- ...( ( c . contextList || acc . contextList ) && {
78
- contextList : {
79
- filePaths : [
80
- ...( acc . contextList ?. filePaths ?? [ ] ) ,
81
- ...( c . contextList ?. filePaths ?? [ ] ) ,
82
- ] ,
83
- rootFolderTitle : c . contextList ?. rootFolderTitle
84
- ? c . contextList . rootFolderTitle
85
- : ( acc . contextList ?. rootFolderTitle ?? '' ) ,
86
- } ,
87
- } ) ,
100
+ ...( am . messageId === c . messageId &&
101
+ ( c . contextList || acc . contextList ) && {
102
+ contextList : {
103
+ filePaths : [
104
+ ...( acc . contextList ?. filePaths ?? [ ] ) ,
105
+ ...( c . contextList ?. filePaths ?? [ ] ) ,
106
+ ] ,
107
+ rootFolderTitle : c . contextList ?. rootFolderTitle
108
+ ? c . contextList . rootFolderTitle
109
+ : ( acc . contextList ?. rootFolderTitle ?? '' ) ,
110
+ } ,
111
+ } ) ,
88
112
header : c . header ? { ...c . header } : { ...am . header } ,
89
113
} ) ) ,
90
114
}
0 commit comments