@@ -169,6 +169,41 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
169169 ) ;
170170 }
171171
172+ private async _writeChatHistoryToFile (
173+ chat : GeminiChat | OllamaChat ,
174+ ) : Promise < void > {
175+ const history = await chat . getHistory ( ) ;
176+ let fileContent = 'Chat History\n\n' ;
177+ for ( const message of history ) {
178+ let content = '' ;
179+ for ( const part of message ?. parts ?? [ ] ) {
180+ if ( 'text' in part && part . text ) {
181+ content += part . text ;
182+ }
183+ if ( 'functionCall' in part && part . functionCall ) {
184+ content += `Function Call: ${
185+ part . functionCall . name
186+ } \nArguments: ${ JSON . stringify (
187+ part . functionCall . args ?? { } ,
188+ null ,
189+ 2 ,
190+ ) } \n`;
191+ }
192+ if ( 'functionResponse' in part && part . functionResponse ) {
193+ content += `Function Response: ${
194+ part . functionResponse . name
195+ } \nOutput: ${ JSON . stringify (
196+ part . functionResponse . response ?? { } ,
197+ null ,
198+ 2 ,
199+ ) } \n`;
200+ }
201+ }
202+ fileContent += `--- ROLE: ${ message . role } ---\n${ content } \n---\n` ;
203+ }
204+ await fs . writeFile ( `chat_history.txt` , fileContent ) ;
205+ }
206+
172207 /**
173208 * Constructs a new AgentExecutor instance.
174209 *
@@ -227,6 +262,8 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
227262 this . callModel ( chat , currentMessage , tools , turnSignal , promptId ) ,
228263 ) ;
229264
265+ await this . _writeChatHistoryToFile ( chat ) ;
266+
230267 if ( turnSignal . aborted ) {
231268 debugLogger . log (
232269 `[Debug] Turn aborted after callModel. Hard abort status: ${ signalManager . isCurrentInterruptHard ( ) } .` ,
@@ -514,6 +551,8 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
514551 } ;
515552
516553 while ( true ) {
554+ await this . _writeChatHistoryToFile ( chat ) ;
555+
517556 debugLogger . log (
518557 `[AgentExecutor] Starting turn ${ turnCounter } for agent ${ this . agentId } ` ,
519558 ) ;
@@ -544,6 +583,8 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
544583 query , // Pass the objective here
545584 ) ;
546585
586+ await this . _writeChatHistoryToFile ( chat ) ;
587+
547588 if ( turnResult . status === 'stop' ) {
548589 terminateReason = turnResult . terminateReason ;
549590
@@ -1395,15 +1436,17 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
13951436 debugLogger . log (
13961437 `[AgentExecutor] Summarized output for tool: ${ functionCall . name } (ID: ${ callId } )` ,
13971438 ) ;
1439+ // Replace the original tool output with the summary.
13981440 for ( const part of toolResponsePartsToReturn ) {
13991441 if ( 'functionResponse' in part && part . functionResponse ) {
1400- const responseObject = part . functionResponse . response as {
1401- llmContent ?: unknown ;
1442+ // By replacing the entire response object, we don't have to
1443+ // worry about what the original properties were (e.g. 'result'
1444+ // vs 'output'). The model will see a generic response containing
1445+ // the summarized text.
1446+ part . functionResponse . response = {
1447+ summary,
14021448 } ;
1403- if ( responseObject . llmContent ) {
1404- responseObject . llmContent = summary ;
1405- break ; // Assume only one functionResponse part
1406- }
1449+ break ; // Assume only one functionResponse part
14071450 }
14081451 }
14091452 }
0 commit comments