Skip to content

Commit ad29f88

Browse files
authored
Merge branch 'feature/agentic-chat' into pair-programming-mode
2 parents 8984aa0 + aefe920 commit ad29f88

File tree

8 files changed

+252
-267
lines changed

8 files changed

+252
-267
lines changed

packages/core/src/codewhispererChat/controllers/chat/controller.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ export class ChatController {
375375
private async processStopResponseMessage(message: StopResponseMessage) {
376376
const session = this.sessionStorage.getSession(message.tabID)
377377
session.tokenSource.cancel()
378+
this.chatHistoryStorage.getTabHistory(message.tabID).clearRecentHistory()
378379
}
379380

380381
private async processTriggerTabIDReceived(message: TriggerTabIDReceived) {
@@ -721,6 +722,8 @@ export class ChatController {
721722
const session = this.sessionStorage.getSession(tabID)
722723
const toolUse = session.toolUse
723724
if (!toolUse || !toolUse.input) {
725+
// Turn off AgentLoop flag if there's no tool use
726+
this.sessionStorage.setAgentLoopInProgress(tabID, false)
724727
return
725728
}
726729
session.setToolUse(undefined)
@@ -794,7 +797,6 @@ export class ChatController {
794797
customization: getSelectedCustomization(),
795798
toolResults: toolResults,
796799
origin: Origin.IDE,
797-
chatHistory: this.chatHistoryStorage.getTabHistory(tabID).getHistory(),
798800
context: session.context ?? [],
799801
relevantTextDocuments: [],
800802
additionalContents: [],
@@ -985,10 +987,16 @@ export class ChatController {
985987
errorMessage = e.message
986988
}
987989

990+
// Turn off AgentLoop flag in case of exception
991+
if (tabID) {
992+
this.sessionStorage.setAgentLoopInProgress(tabID, false)
993+
}
994+
988995
this.messenger.sendErrorMessage(errorMessage, tabID, requestID)
989996
getLogger().error(`error: ${errorMessage} tabID: ${tabID} requestID: ${requestID}`)
990997

991998
this.sessionStorage.deleteSession(tabID)
999+
this.chatHistoryStorage.getTabHistory(tabID).clearRecentHistory()
9921000
}
9931001

9941002
private async processContextMenuCommand(command: EditorContextCommand) {
@@ -1148,7 +1156,6 @@ export class ChatController {
11481156
codeQuery: lastTriggerEvent.context?.focusAreaContext?.names,
11491157
userIntent: message.userIntent,
11501158
customization: getSelectedCustomization(),
1151-
chatHistory: this.chatHistoryStorage.getTabHistory(message.tabID).getHistory(),
11521159
contextLengths: {
11531160
...defaultContextLengths,
11541161
},
@@ -1197,7 +1204,6 @@ export class ChatController {
11971204
codeQuery: context?.focusAreaContext?.names,
11981205
userIntent: undefined,
11991206
customization: getSelectedCustomization(),
1200-
chatHistory: this.chatHistoryStorage.getTabHistory(message.tabID).getHistory(),
12011207
origin: Origin.IDE,
12021208
context: message.context ?? [],
12031209
relevantTextDocuments: [],
@@ -1379,6 +1385,16 @@ export class ChatController {
13791385
}
13801386

13811387
const tabID = triggerEvent.tabID
1388+
if (this.sessionStorage.isAgentLoopInProgress(tabID)) {
1389+
// If a response is already in progress, stop it first
1390+
const stopResponseMessage: StopResponseMessage = {
1391+
tabID: tabID,
1392+
}
1393+
await this.processStopResponseMessage(stopResponseMessage)
1394+
}
1395+
1396+
// Ensure AgentLoop flag is set to true during response generation
1397+
this.sessionStorage.setAgentLoopInProgress(tabID, true)
13821398

13831399
const credentialsState = await AuthUtil.instance.getChatAuthState()
13841400

@@ -1442,6 +1458,7 @@ export class ChatController {
14421458
if (fixedHistoryMessage.userInputMessage?.userInputMessageContext) {
14431459
triggerPayload.toolResults = fixedHistoryMessage.userInputMessage.userInputMessageContext.toolResults
14441460
}
1461+
triggerPayload.chatHistory = chatHistory.getHistory()
14451462
const request = triggerPayloadToChatRequest(triggerPayload)
14461463
const conversationId = chatHistory.getConversationId() || randomUUID()
14471464
chatHistory.setConversationId(conversationId)
@@ -1496,16 +1513,23 @@ export class ChatController {
14961513
}
14971514
this.telemetryHelper.recordEnterFocusConversation(triggerEvent.tabID)
14981515
this.telemetryHelper.recordStartConversation(triggerEvent, triggerPayload)
1499-
chatHistory.appendUserMessage(fixedHistoryMessage)
1516+
if (request.conversationState.currentMessage) {
1517+
chatHistory.appendUserMessage(request.conversationState.currentMessage)
1518+
}
15001519

15011520
getLogger().info(
15021521
`response to tab: ${tabID} conversationID: ${session.sessionIdentifier} requestID: ${
15031522
response.$metadata.requestId
15041523
} metadata: ${inspect(response.$metadata, { depth: 12 })}`
15051524
)
15061525
await this.messenger.sendAIResponse(response, session, tabID, triggerID, triggerPayload, chatHistory)
1526+
1527+
// Turn off AgentLoop flag after sending the AI response
1528+
this.sessionStorage.setAgentLoopInProgress(tabID, false)
15071529
} catch (e: any) {
15081530
this.telemetryHelper.recordMessageResponseError(triggerPayload, tabID, getHttpStatusCode(e) ?? 0)
1531+
// Turn off AgentLoop flag in case of exception
1532+
this.sessionStorage.setAgentLoopInProgress(tabID, false)
15091533
// clears session, record telemetry before this call
15101534
this.processException(e, tabID)
15111535
}

packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@ import { ChatItemButton, ChatItemContent, ChatItemFormItem, MynahIconsType, Myna
4444
import { ChatHistoryManager } from '../../../storages/chatHistory'
4545
import { ToolType, ToolUtils } from '../../../tools/toolUtils'
4646
import { ChatStream } from '../../../tools/chatStream'
47-
import { getWorkspaceForFile } from '../../../../shared/utilities/workspaceUtils'
4847
import path from 'path'
4948
import { CommandValidation } from '../../../tools/executeBash'
5049
import { noWriteTools, tools } from '../../../constants'
50+
import { Change } from 'diff'
51+
import { FsWriteParams } from '../../../tools/fsWrite'
5152

5253
export type StaticTextResponseType = 'quick-action-help' | 'onboarding-help' | 'transform' | 'help'
5354

@@ -232,8 +233,10 @@ export class Messenger {
232233

233234
const tool = ToolUtils.tryFromToolUse(toolUse)
234235
if ('type' in tool) {
236+
let changeList: Change[] | undefined = undefined
235237
if (tool.type === ToolType.FsWrite) {
236238
session.setShowDiffOnFileWrite(true)
239+
changeList = await tool.tool.getDiffChanges()
237240
}
238241
if (
239242
tool.type === ToolType.FsWrite ||
@@ -252,7 +255,8 @@ export class Messenger {
252255
triggerID,
253256
toolUse,
254257
validation,
255-
session.messageIdToUpdate
258+
session.messageIdToUpdate,
259+
changeList
256260
)
257261
await ToolUtils.queueDescription(tool, chatStream)
258262

@@ -333,7 +337,7 @@ export class Messenger {
333337
}
334338
return true
335339
},
336-
{ timeout: 60000, truthy: true }
340+
{ timeout: 600000, truthy: true }
337341
)
338342
.catch((error: any) => {
339343
let errorMessage = 'Error reading chat stream.'
@@ -493,7 +497,8 @@ export class Messenger {
493497
triggerID: string,
494498
toolUse: ToolUse | undefined,
495499
validation: CommandValidation,
496-
messageIdToUpdate: string | undefined
500+
messageIdToUpdate: string | undefined,
501+
changeList?: Change[]
497502
) {
498503
const buttons: ChatItemButton[] = []
499504
let fileList: ChatItemContent['fileList'] = undefined
@@ -508,24 +513,29 @@ export class Messenger {
508513
message = validation.warning + message
509514
}
510515
} else if (toolUse?.name === ToolType.FsWrite) {
511-
const absoluteFilePath = (toolUse?.input as any).path
512-
const projectPath = getWorkspaceForFile(absoluteFilePath)
513-
const relativePath = projectPath ? path.relative(projectPath, absoluteFilePath) : absoluteFilePath
516+
const input = toolUse.input as unknown as FsWriteParams
517+
const fileName = path.basename(input.path)
518+
const changes = changeList?.reduce(
519+
(acc, { count = 0, added, removed }) => {
520+
if (added) {
521+
acc.added += count
522+
} else if (removed) {
523+
acc.deleted += count
524+
}
525+
return acc
526+
},
527+
{ added: 0, deleted: 0 }
528+
)
514529
// FileList
515530
fileList = {
516531
fileTreeTitle: '',
517532
hideFileCount: true,
518-
filePaths: [relativePath],
533+
filePaths: [fileName],
519534
details: {
520-
[relativePath]: {
535+
[fileName]: {
521536
// eslint-disable-next-line unicorn/no-null
522537
icon: null,
523-
label: 'Created',
524-
changes: {
525-
added: 36,
526-
deleted: 0,
527-
total: 36,
528-
},
538+
changes: changes,
529539
},
530540
},
531541
}

0 commit comments

Comments
 (0)