Skip to content

Commit 8320c90

Browse files
authored
Merge branch 'feature/agentic-chat' into fsReadFix
2 parents 67dcd77 + 04f3bf9 commit 8320c90

File tree

20 files changed

+1043
-467
lines changed

20 files changed

+1043
-467
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "Code fix line number or file is sometimes not accurate"
4+
}

packages/core/src/amazonq/webview/ui/apps/cwChatConnector.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,19 +285,18 @@ export class Connector extends BaseConnector {
285285
}
286286

287287
if (messageData.type === 'customFormActionMessage') {
288-
this.onCustomFormAction(messageData.tabID, messageData.messageId, messageData.action)
288+
this.onCustomFormAction(messageData.tabID, messageData.messageId, messageData.action, messageData.triggerId)
289289
return
290290
}
291291

292292
if (messageData.type === 'asyncEventProgressMessage') {
293-
const enableStopAction = false
294293
const isPromptInputDisabled = true
295294
this.onAsyncEventProgress(
296295
messageData.tabID,
297296
messageData.inProgress,
298297
messageData.message ?? undefined,
299298
messageData.messageId ?? undefined,
300-
enableStopAction,
299+
messageData.inProgress,
301300
isPromptInputDisabled
302301
)
303302
return
@@ -335,7 +334,8 @@ export class Connector extends BaseConnector {
335334
id: string
336335
text?: string | undefined
337336
formItemValues?: Record<string, string> | undefined
338-
}
337+
},
338+
triggerId: string
339339
) {
340340
if (action === undefined) {
341341
return
@@ -351,6 +351,7 @@ export class Connector extends BaseConnector {
351351
formSelectedValues: action.formItemValues,
352352
tabType: this.getTabType(),
353353
tabID: tabId,
354+
triggerId: triggerId,
354355
})
355356

356357
if (

packages/core/src/amazonq/webview/ui/connector.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ export class Connector {
744744
tabType: 'cwc',
745745
})
746746
} else {
747-
this.cwChatConnector.onCustomFormAction(tabId, messageId ?? '', action)
747+
this.cwChatConnector.onCustomFormAction(tabId, messageId ?? '', action, messageId ?? '')
748748
}
749749
break
750750
case 'agentWalkthrough': {

packages/core/src/amazonq/webview/ui/main.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,13 @@ export const createMynahUI = (
719719
return
720720
}
721721

722+
// For new user prompt stopping chat with UI changes
723+
mynahUI.updateStore(tabID, {
724+
loadingChat: false,
725+
promptInputDisabledState: false,
726+
})
727+
connector.onStopChatResponse(tabID)
728+
722729
const tabType = tabsStorage.getTab(tabID)?.type
723730
if (tabType === 'featuredev') {
724731
mynahUI.addChatItem(tabID, {

packages/core/src/codewhisperer/commands/startCodeFixGeneration.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { TelemetryHelper } from '../util/telemetryHelper'
2020
import { tempDirPath } from '../../shared/filesystemUtilities'
2121
import { CodeWhispererSettings } from '../util/codewhispererSettings'
2222
import { AuthUtil } from '../util/authUtil'
23+
import { saveDocumentIfDirty } from '../../shared/utilities/textDocumentUtilities'
2324

2425
export async function startCodeFixGeneration(
2526
client: DefaultCodeWhispererClient,
@@ -44,6 +45,9 @@ export async function startCodeFixGeneration(
4445
* Step 1: Generate zip
4546
*/
4647
throwIfCancelled()
48+
49+
// Save the file if it has unsaved changes to ensure the latest content is included in the zip
50+
await saveDocumentIfDirty(filePath)
4751
const admZip = new AdmZip()
4852
admZip.addLocalFile(filePath)
4953

packages/core/src/codewhisperer/service/securityIssueProvider.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ export class SecurityIssueProvider {
4848
.filter((issue) => {
4949
const range = new vscode.Range(
5050
issue.startLine,
51-
event.document.lineAt(issue.startLine)?.range.start.character ?? 0,
52-
issue.endLine,
53-
event.document.lineAt(issue.endLine - 1)?.range.end.character ?? 0
51+
0,
52+
issue.startLine === issue.endLine ? issue.endLine + 1 : issue.endLine,
53+
0
5454
)
55+
5556
const intersection = changedRange.intersection(range)
5657
return !(intersection && (/\S/.test(changedText) || changedText === ''))
5758
})

packages/core/src/codewhispererChat/clients/chat/v0/chat.ts

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ import { createQDeveloperStreamingClient } from '../../../../shared/clients/qDev
1616
import { UserWrittenCodeTracker } from '../../../../codewhisperer/tracker/userWrittenCodeTracker'
1717
import { DocumentReference, PromptMessage } from '../../../controllers/chat/model'
1818
import { FsWriteBackup } from '../../../../codewhispererChat/tools/fsWrite'
19+
import { randomUUID } from '../../../../shared/crypto'
20+
import { getLogger } from '../../../../shared/logger/logger'
1921

2022
export type ToolUseWithError = {
2123
toolUse: ToolUse
2224
error: Error | undefined
2325
}
24-
import { getLogger } from '../../../../shared/logger/logger'
25-
import { randomUUID } from '../../../../shared/crypto'
2626

2727
export class ChatSession {
28-
private sessionId?: string
28+
private sessionId: string
2929
/**
3030
* _readFiles = list of files read from the project to gather context before generating response.
3131
* _showDiffOnFileWrite = Controls whether to show diff view (true) or file context view (false) to the user
@@ -39,6 +39,8 @@ export class ChatSession {
3939
private _context: PromptMessage['context']
4040
private _pairProgrammingModeOn: boolean = true
4141
private _fsWriteBackups: Map<string, FsWriteBackup> = new Map()
42+
private _agenticLoopInProgress: boolean = false
43+
4244
/**
4345
* True if messages from local history have been sent to session.
4446
*/
@@ -50,7 +52,7 @@ export class ChatSession {
5052
// TODO: doesn't handle the edge case when two files share the same relativePath string but from different root
5153
// e.g. root_a/file1 vs root_b/file1
5254
relativePathToWorkspaceRoot: Map<string, string> = new Map()
53-
public get sessionIdentifier(): string | undefined {
55+
public get sessionIdentifier(): string {
5456
return this.sessionId
5557
}
5658
public get messageIdToUpdate(): string | undefined {
@@ -69,6 +71,33 @@ export class ChatSession {
6971
this._messageIdToUpdateListDirectory = messageId
7072
}
7173

74+
public get agenticLoopInProgress(): boolean {
75+
return this._agenticLoopInProgress
76+
}
77+
78+
public setAgenticLoopInProgress(value: boolean) {
79+
// When setting agenticLoop to false (ending the loop), dispose the current token source
80+
if (this._agenticLoopInProgress === true && value === false) {
81+
this.disposeTokenSource()
82+
// Create a new token source for future operations
83+
this.createNewTokenSource()
84+
}
85+
this._agenticLoopInProgress = value
86+
}
87+
88+
/**
89+
* Safely disposes the current token source if it exists
90+
*/
91+
disposeTokenSource() {
92+
if (this.tokenSource) {
93+
try {
94+
this.tokenSource.dispose()
95+
} catch (error) {
96+
getLogger().debug(`Error disposing token source: ${error}`)
97+
}
98+
}
99+
}
100+
72101
public get pairProgrammingModeOn(): boolean {
73102
return this._pairProgrammingModeOn
74103
}
@@ -105,13 +134,14 @@ export class ChatSession {
105134

106135
constructor() {
107136
this.createNewTokenSource()
137+
this.sessionId = randomUUID()
108138
}
109139

110140
createNewTokenSource() {
111141
this.tokenSource = new vscode.CancellationTokenSource()
112142
}
113143

114-
public setSessionID(id?: string) {
144+
public setSessionID(id: string) {
115145
this.sessionId = id
116146
}
117147
public get readFiles(): DocumentReference[] {
@@ -148,14 +178,6 @@ export class ChatSession {
148178
)
149179
}
150180

151-
const responseStream = response.sendMessageResponse
152-
for await (const event of responseStream) {
153-
if ('messageMetadataEvent' in event) {
154-
this.sessionId = event.messageMetadataEvent?.conversationId
155-
break
156-
}
157-
}
158-
159181
UserWrittenCodeTracker.instance.onQFeatureInvoked()
160182
return response
161183
}
@@ -170,12 +192,6 @@ export class ChatSession {
170192
)
171193
}
172194

173-
this.sessionId = response.conversationId
174-
if (this.sessionId?.length === 0) {
175-
getLogger().debug(`Session ID: ${this.sessionId} is empty. Generating random UUID`)
176-
this.sessionId = randomUUID()
177-
}
178-
179195
UserWrittenCodeTracker.instance.onQFeatureInvoked()
180196

181197
return response

0 commit comments

Comments
 (0)