Skip to content

Commit 4504d1d

Browse files
Merge branch 'feature/agentic-chat' into my-feature-agentic
2 parents 5831745 + aefe920 commit 4504d1d

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
@@ -368,6 +368,7 @@ export class ChatController {
368368
private async processStopResponseMessage(message: StopResponseMessage) {
369369
const session = this.sessionStorage.getSession(message.tabID)
370370
session.tokenSource.cancel()
371+
this.chatHistoryStorage.getTabHistory(message.tabID).clearRecentHistory()
371372
}
372373

373374
private async processTriggerTabIDReceived(message: TriggerTabIDReceived) {
@@ -650,6 +651,8 @@ export class ChatController {
650651
const session = this.sessionStorage.getSession(tabID)
651652
const toolUse = session.toolUse
652653
if (!toolUse || !toolUse.input) {
654+
// Turn off AgentLoop flag if there's no tool use
655+
this.sessionStorage.setAgentLoopInProgress(tabID, false)
653656
return
654657
}
655658
session.setToolUse(undefined)
@@ -723,7 +726,6 @@ export class ChatController {
723726
customization: getSelectedCustomization(),
724727
toolResults: toolResults,
725728
origin: Origin.IDE,
726-
chatHistory: this.chatHistoryStorage.getTabHistory(tabID).getHistory(),
727729
context: session.context ?? [],
728730
relevantTextDocuments: [],
729731
additionalContents: [],
@@ -899,10 +901,16 @@ export class ChatController {
899901
errorMessage = e.message
900902
}
901903

904+
// Turn off AgentLoop flag in case of exception
905+
if (tabID) {
906+
this.sessionStorage.setAgentLoopInProgress(tabID, false)
907+
}
908+
902909
this.messenger.sendErrorMessage(errorMessage, tabID, requestID)
903910
getLogger().error(`error: ${errorMessage} tabID: ${tabID} requestID: ${requestID}`)
904911

905912
this.sessionStorage.deleteSession(tabID)
913+
this.chatHistoryStorage.getTabHistory(tabID).clearRecentHistory()
906914
}
907915

908916
private async processContextMenuCommand(command: EditorContextCommand) {
@@ -1062,7 +1070,6 @@ export class ChatController {
10621070
codeQuery: lastTriggerEvent.context?.focusAreaContext?.names,
10631071
userIntent: message.userIntent,
10641072
customization: getSelectedCustomization(),
1065-
chatHistory: this.chatHistoryStorage.getTabHistory(message.tabID).getHistory(),
10661073
contextLengths: {
10671074
...defaultContextLengths,
10681075
},
@@ -1111,7 +1118,6 @@ export class ChatController {
11111118
codeQuery: context?.focusAreaContext?.names,
11121119
userIntent: undefined,
11131120
customization: getSelectedCustomization(),
1114-
chatHistory: this.chatHistoryStorage.getTabHistory(message.tabID).getHistory(),
11151121
origin: Origin.IDE,
11161122
context: message.context ?? [],
11171123
relevantTextDocuments: [],
@@ -1293,6 +1299,16 @@ export class ChatController {
12931299
}
12941300

12951301
const tabID = triggerEvent.tabID
1302+
if (this.sessionStorage.isAgentLoopInProgress(tabID)) {
1303+
// If a response is already in progress, stop it first
1304+
const stopResponseMessage: StopResponseMessage = {
1305+
tabID: tabID,
1306+
}
1307+
await this.processStopResponseMessage(stopResponseMessage)
1308+
}
1309+
1310+
// Ensure AgentLoop flag is set to true during response generation
1311+
this.sessionStorage.setAgentLoopInProgress(tabID, true)
12961312

12971313
const credentialsState = await AuthUtil.instance.getChatAuthState()
12981314

@@ -1355,6 +1371,7 @@ export class ChatController {
13551371
if (fixedHistoryMessage.userInputMessage?.userInputMessageContext) {
13561372
triggerPayload.toolResults = fixedHistoryMessage.userInputMessage.userInputMessageContext.toolResults
13571373
}
1374+
triggerPayload.chatHistory = chatHistory.getHistory()
13581375
const request = triggerPayloadToChatRequest(triggerPayload)
13591376
const conversationId = chatHistory.getConversationId() || randomUUID()
13601377
chatHistory.setConversationId(conversationId)
@@ -1409,16 +1426,23 @@ export class ChatController {
14091426
}
14101427
this.telemetryHelper.recordEnterFocusConversation(triggerEvent.tabID)
14111428
this.telemetryHelper.recordStartConversation(triggerEvent, triggerPayload)
1412-
chatHistory.appendUserMessage(fixedHistoryMessage)
1429+
if (request.conversationState.currentMessage) {
1430+
chatHistory.appendUserMessage(request.conversationState.currentMessage)
1431+
}
14131432

14141433
getLogger().info(
14151434
`response to tab: ${tabID} conversationID: ${session.sessionIdentifier} requestID: ${
14161435
response.$metadata.requestId
14171436
} metadata: ${inspect(response.$metadata, { depth: 12 })}`
14181437
)
14191438
await this.messenger.sendAIResponse(response, session, tabID, triggerID, triggerPayload, chatHistory)
1439+
1440+
// Turn off AgentLoop flag after sending the AI response
1441+
this.sessionStorage.setAgentLoopInProgress(tabID, false)
14201442
} catch (e: any) {
14211443
this.telemetryHelper.recordMessageResponseError(triggerPayload, tabID, getHttpStatusCode(e) ?? 0)
1444+
// Turn off AgentLoop flag in case of exception
1445+
this.sessionStorage.setAgentLoopInProgress(tabID, false)
14221446
// clears session, record telemetry before this call
14231447
this.processException(e, tabID)
14241448
}

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 { extractErrorInfo } from '../../../../shared/utilities/messageUtil'
50+
import { Change } from 'diff'
51+
import { FsWriteParams } from '../../../tools/fsWrite'
5152

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

@@ -220,8 +221,10 @@ export class Messenger {
220221

221222
const tool = ToolUtils.tryFromToolUse(toolUse)
222223
if ('type' in tool) {
224+
let changeList: Change[] | undefined = undefined
223225
if (tool.type === ToolType.FsWrite) {
224226
session.setShowDiffOnFileWrite(true)
227+
changeList = await tool.tool.getDiffChanges()
225228
}
226229
if (
227230
tool.type === ToolType.FsWrite ||
@@ -240,7 +243,8 @@ export class Messenger {
240243
triggerID,
241244
toolUse,
242245
validation,
243-
session.messageIdToUpdate
246+
session.messageIdToUpdate,
247+
changeList
244248
)
245249
await ToolUtils.queueDescription(tool, chatStream)
246250

@@ -324,7 +328,7 @@ export class Messenger {
324328
}
325329
return true
326330
},
327-
{ timeout: 60000, truthy: true }
331+
{ timeout: 600000, truthy: true }
328332
)
329333
.catch((error: any) => {
330334
const errorInfo = extractErrorInfo(error)
@@ -479,7 +483,8 @@ export class Messenger {
479483
triggerID: string,
480484
toolUse: ToolUse | undefined,
481485
validation: CommandValidation,
482-
messageIdToUpdate: string | undefined
486+
messageIdToUpdate: string | undefined,
487+
changeList?: Change[]
483488
) {
484489
const buttons: ChatItemButton[] = []
485490
let fileList: ChatItemContent['fileList'] = undefined
@@ -494,24 +499,29 @@ export class Messenger {
494499
message = validation.warning + message
495500
}
496501
} else if (toolUse?.name === ToolType.FsWrite) {
497-
const absoluteFilePath = (toolUse?.input as any).path
498-
const projectPath = getWorkspaceForFile(absoluteFilePath)
499-
const relativePath = projectPath ? path.relative(projectPath, absoluteFilePath) : absoluteFilePath
502+
const input = toolUse.input as unknown as FsWriteParams
503+
const fileName = path.basename(input.path)
504+
const changes = changeList?.reduce(
505+
(acc, { count = 0, added, removed }) => {
506+
if (added) {
507+
acc.added += count
508+
} else if (removed) {
509+
acc.deleted += count
510+
}
511+
return acc
512+
},
513+
{ added: 0, deleted: 0 }
514+
)
500515
// FileList
501516
fileList = {
502517
fileTreeTitle: '',
503518
hideFileCount: true,
504-
filePaths: [relativePath],
519+
filePaths: [fileName],
505520
details: {
506-
[relativePath]: {
521+
[fileName]: {
507522
// eslint-disable-next-line unicorn/no-null
508523
icon: null,
509-
label: 'Created',
510-
changes: {
511-
added: 36,
512-
deleted: 0,
513-
total: 36,
514-
},
524+
changes: changes,
515525
},
516526
},
517527
}

0 commit comments

Comments
 (0)