Skip to content

Commit e3ea894

Browse files
committed
feat(chat): add confirmation buttons and tool descriptions
1 parent 7ece541 commit e3ea894

File tree

4 files changed

+62
-11
lines changed

4 files changed

+62
-11
lines changed

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

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,24 @@ export class Messenger {
215215

216216
const tool = ToolUtils.tryFromToolUse(toolUse)
217217
if ('type' in tool) {
218-
const chatStream = new ChatStream(this, tabID, triggerID, toolUse.toolUseId)
219-
ToolUtils.queueDescription(tool, chatStream)
218+
const requiresAcceptance = ToolUtils.requiresAcceptance(tool)
220219

221-
this.dispatcher.sendCustomFormActionMessage(
222-
new CustomFormActionMessage(tabID, {
223-
id: 'confirm-tool-use',
224-
})
220+
const chatStream = new ChatStream(
221+
this,
222+
tabID,
223+
triggerID,
224+
toolUse.toolUseId,
225+
requiresAcceptance
225226
)
227+
ToolUtils.queueDescription(tool, chatStream)
228+
229+
if (!requiresAcceptance) {
230+
this.dispatcher.sendCustomFormActionMessage(
231+
new CustomFormActionMessage(tabID, {
232+
id: 'confirm-tool-use',
233+
})
234+
)
235+
}
226236
} else {
227237
// TODO: Handle the error
228238
}
@@ -418,7 +428,22 @@ export class Messenger {
418428
)
419429
}
420430

421-
public sendPartialToolLog(message: string, tabID: string, triggerID: string, toolUseId: string | undefined) {
431+
public sendPartialToolLog(
432+
message: string,
433+
tabID: string,
434+
triggerID: string,
435+
toolUseId: string | undefined,
436+
requiresAcceptance = false
437+
) {
438+
const buttons: ChatItemButton[] = []
439+
if (requiresAcceptance) {
440+
buttons.push({
441+
id: 'confirm-tool-use',
442+
text: 'Confirm',
443+
position: 'outside',
444+
})
445+
}
446+
422447
this.dispatcher.sendChatMessage(
423448
new ChatMessage(
424449
{
@@ -433,6 +458,7 @@ export class Messenger {
433458
codeBlockLanguage: undefined,
434459
contextList: undefined,
435460
canBeVoted: false,
461+
buttons,
436462
},
437463
tabID
438464
)

packages/core/src/codewhispererChat/tools/chatStream.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export class ChatStream extends Writable {
1919
private readonly tabID: string,
2020
private readonly triggerID: string,
2121
private readonly toolUseId: string | undefined,
22+
private readonly requiresAcceptance = false,
2223
private readonly logger = getLogger('chatStream')
2324
) {
2425
super()
@@ -30,13 +31,25 @@ export class ChatStream extends Writable {
3031
const text = chunk.toString()
3132
this.accumulatedLogs += text
3233
this.logger.debug(`ChatStream received chunk: ${text}`)
33-
this.messenger.sendPartialToolLog(this.accumulatedLogs, this.tabID, this.triggerID, this.toolUseId)
34+
this.messenger.sendPartialToolLog(
35+
this.accumulatedLogs,
36+
this.tabID,
37+
this.triggerID,
38+
this.toolUseId,
39+
this.requiresAcceptance
40+
)
3441
callback()
3542
}
3643

3744
override _final(callback: (error?: Error | null) => void): void {
3845
if (this.accumulatedLogs.trim().length > 0) {
39-
this.messenger.sendPartialToolLog(this.accumulatedLogs, this.tabID, this.triggerID, this.toolUseId)
46+
this.messenger.sendPartialToolLog(
47+
this.accumulatedLogs,
48+
this.tabID,
49+
this.triggerID,
50+
this.toolUseId,
51+
this.requiresAcceptance
52+
)
4053
}
4154
callback()
4255
}

packages/core/src/codewhispererChat/tools/fsRead.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { readDirectoryRecursively } from '../../shared/utilities/workspaceUtils'
88
import fs from '../../shared/fs/fs'
99
import { InvokeOutput, maxToolResponseSize, OutputKind, sanitizePath } from './toolShared'
1010
import { Writable } from 'stream'
11+
import path from 'path'
1112

1213
export interface FsReadParams {
1314
path: string
@@ -49,7 +50,12 @@ export class FsRead {
4950
this.logger.debug(`Validation succeeded for path: ${this.fsPath}`)
5051
}
5152

52-
public queueDescription(updates: Writable): void {}
53+
public queueDescription(updates: Writable): void {
54+
const fileName = path.basename(this.fsPath)
55+
const fileUri = vscode.Uri.file(this.fsPath)
56+
updates.write(`Reading: [${fileName}](${fileUri})`)
57+
updates.end()
58+
}
5359

5460
public async invoke(updates: Writable): Promise<InvokeOutput> {
5561
try {

packages/core/src/codewhispererChat/tools/fsWrite.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { getLogger } from '../../shared/logger/logger'
88
import vscode from 'vscode'
99
import { fs } from '../../shared/fs/fs'
1010
import { Writable } from 'stream'
11+
import path from 'path'
1112

1213
interface BaseParams {
1314
path: string
@@ -69,7 +70,12 @@ export class FsWrite {
6970
}
7071
}
7172

72-
public queueDescription(updates: Writable): void {}
73+
public queueDescription(updates: Writable): void {
74+
const fileName = path.basename(this.params.path)
75+
const fileUri = vscode.Uri.file(this.params.path)
76+
updates.write(`Writing to: [${fileName}](${fileUri})`)
77+
updates.end()
78+
}
7379

7480
public async validate(): Promise<void> {
7581
switch (this.params.command) {

0 commit comments

Comments
 (0)