Skip to content

Commit 7ece541

Browse files
authored
Merge pull request aws#6873 from ctlai95/generic-chat-stream
feat(chat): use ChatStream to show tool description
2 parents 8749cd7 + 70e56bd commit 7ece541

File tree

3 files changed

+24
-117
lines changed

3 files changed

+24
-117
lines changed

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

Lines changed: 15 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ import { extractAuthFollowUp } from '../../../../amazonq/util/authUtils'
4141
import { helpMessage } from '../../../../amazonq/webview/ui/texts/constants'
4242
import { ChatItemButton, ChatItemFormItem, MynahUIDataModel } from '@aws/mynah-ui'
4343
import { ChatHistoryManager } from '../../../storages/chatHistory'
44-
import { ExecuteBashParams } from '../../../tools/executeBash'
45-
import { FsWriteParams } from '../../../tools/fsWrite'
44+
import { ToolUtils } from '../../../tools/toolUtils'
45+
import { ChatStream } from '../../../tools/chatStream'
4646

4747
export type StaticTextResponseType = 'quick-action-help' | 'onboarding-help' | 'transform' | 'help'
4848

@@ -213,39 +213,19 @@ export class Messenger {
213213
toolUse.name = cwChatEvent.toolUseEvent.name ?? ''
214214
session.setToolUse(toolUse)
215215

216-
const message = this.getToolUseMessage(toolUse)
217-
// const isConfirmationRequired = this.getIsConfirmationRequired(toolUse)
216+
const tool = ToolUtils.tryFromToolUse(toolUse)
217+
if ('type' in tool) {
218+
const chatStream = new ChatStream(this, tabID, triggerID, toolUse.toolUseId)
219+
ToolUtils.queueDescription(tool, chatStream)
218220

219-
// TODO: If toolUse is fs_write then session.setShowDiffOnFileWrite(true)
220-
221-
this.dispatcher.sendChatMessage(
222-
new ChatMessage(
223-
{
224-
message,
225-
messageType: 'answer',
226-
followUps: undefined,
227-
followUpsHeader: undefined,
228-
relatedSuggestions: undefined,
229-
codeReference,
230-
triggerID,
231-
messageID: toolUse.toolUseId,
232-
userIntent: triggerPayload.userIntent,
233-
codeBlockLanguage: codeBlockLanguage,
234-
contextList: undefined,
235-
// TODO: confirmation buttons
236-
},
237-
tabID
221+
this.dispatcher.sendCustomFormActionMessage(
222+
new CustomFormActionMessage(tabID, {
223+
id: 'confirm-tool-use',
224+
})
238225
)
239-
)
240-
241-
this.dispatcher.sendCustomFormActionMessage(
242-
new CustomFormActionMessage(tabID, {
243-
id: 'confirm-tool-use',
244-
})
245-
)
246-
// TODO: setup permission action
247-
// if (!isConfirmationRequired) {
248-
// }
226+
} else {
227+
// TODO: Handle the error
228+
}
249229
}
250230

251231
if (
@@ -438,7 +418,7 @@ export class Messenger {
438418
)
439419
}
440420

441-
public sendPartialBashToolLog(message: string, tabID: string, triggerID: string, toolUseId: string | undefined) {
421+
public sendPartialToolLog(message: string, tabID: string, triggerID: string, toolUseId: string | undefined) {
442422
this.dispatcher.sendChatMessage(
443423
new ChatMessage(
444424
{
@@ -450,7 +430,7 @@ export class Messenger {
450430
triggerID,
451431
messageID: toolUseId ?? `tool-output`,
452432
userIntent: undefined,
453-
codeBlockLanguage: 'plaintext',
433+
codeBlockLanguage: undefined,
454434
contextList: undefined,
455435
canBeVoted: false,
456436
},
@@ -617,67 +597,4 @@ export class Messenger {
617597
new ShowCustomFormMessage(tabID, formItems, buttons, title, description)
618598
)
619599
}
620-
621-
// TODO: Make this cleaner
622-
// private getIsConfirmationRequired(toolUse: ToolUse) {
623-
// if (toolUse.name === 'execute_bash') {
624-
// const executeBash = new ExecuteBash(toolUse.input as unknown as ExecuteBashParams)
625-
// return executeBash.requiresAcceptance()
626-
// }
627-
// return toolUse.name === 'fs_write'
628-
// }
629-
private getToolUseMessage(toolUse: ToolUse) {
630-
if (toolUse.name === 'fsRead') {
631-
return `Reading the file at \`${(toolUse.input as any)?.path}\` using the \`fsRead\` tool.`
632-
}
633-
if (toolUse.name === 'executeBash') {
634-
const input = toolUse.input as unknown as ExecuteBashParams
635-
return `Executing the bash command
636-
\`\`\`bash
637-
${input.command}
638-
\`\`\`
639-
using the \`executeBash\` tool.`
640-
}
641-
if (toolUse.name === 'fsWrite') {
642-
const input = toolUse.input as unknown as FsWriteParams
643-
switch (input.command) {
644-
case 'create': {
645-
return `Writing
646-
\`\`\`
647-
${input.fileText}
648-
\`\`\`
649-
into the file at \`${input.path}\` using the \`fsWrite\` tool.`
650-
}
651-
case 'strReplace': {
652-
return `Replacing
653-
\`\`\`
654-
${input.oldStr}
655-
\`\`\`
656-
with
657-
\`\`\`
658-
${input.newStr}
659-
\`\`\`
660-
at \`${input.path}\` using the \`fsWrite\` tool.`
661-
}
662-
case 'insert': {
663-
return `Inserting
664-
\`\`\`
665-
${input.newStr}
666-
\`\`\`
667-
at line
668-
\`\`\`
669-
${input.insertLine}
670-
\`\`\`
671-
at \`${input.path}\` using the \`fsWrite\` tool.`
672-
}
673-
case 'append': {
674-
return `Appending
675-
\`\`\`
676-
${input.newStr}
677-
\`\`\`
678-
at \`${input.path}\` using the \`fsWrite\` tool.`
679-
}
680-
}
681-
}
682-
}
683600
}

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

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,20 @@ export class ChatStream extends Writable {
2323
) {
2424
super()
2525
this.logger.debug(`ChatStream created for tabID: ${tabID}, triggerID: ${triggerID}`)
26+
this.messenger.sendInitalStream(tabID, triggerID, undefined)
2627
}
2728

2829
override _write(chunk: Buffer, encoding: BufferEncoding, callback: (error?: Error | null) => void): void {
2930
const text = chunk.toString()
3031
this.accumulatedLogs += text
3132
this.logger.debug(`ChatStream received chunk: ${text}`)
32-
this.messenger.sendPartialBashToolLog(
33-
`\`\`\`bash\n${this.accumulatedLogs}\`\`\``,
34-
this.tabID,
35-
this.triggerID,
36-
this.toolUseId
37-
)
33+
this.messenger.sendPartialToolLog(this.accumulatedLogs, this.tabID, this.triggerID, this.toolUseId)
3834
callback()
3935
}
4036

4137
override _final(callback: (error?: Error | null) => void): void {
4238
if (this.accumulatedLogs.trim().length > 0) {
43-
this.messenger.sendPartialBashToolLog(
44-
`\`\`\`bash\n${this.accumulatedLogs}\`\`\``,
45-
this.tabID,
46-
this.triggerID,
47-
this.toolUseId
48-
)
39+
this.messenger.sendPartialToolLog(this.accumulatedLogs, this.tabID, this.triggerID, this.toolUseId)
4940
}
5041
callback()
5142
}

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export class ExecuteBash {
7474
const stdoutBuffer: string[] = []
7575
const stderrBuffer: string[] = []
7676

77+
let firstChunk = true
7778
const childProcessOptions: ChildProcessOptions = {
7879
spawnOptions: {
7980
cwd: this.workingDirectory,
@@ -82,7 +83,8 @@ export class ExecuteBash {
8283
collect: false,
8384
waitForStreams: true,
8485
onStdout: (chunk: string) => {
85-
ExecuteBash.handleChunk(chunk, stdoutBuffer, updates)
86+
ExecuteBash.handleChunk(firstChunk ? '```console\n' + chunk : chunk, stdoutBuffer, updates)
87+
firstChunk = false
8688
},
8789
onStderr: (chunk: string) => {
8890
ExecuteBash.handleChunk(chunk, stderrBuffer, updates)
@@ -203,11 +205,8 @@ export class ExecuteBash {
203205
}
204206

205207
public queueDescription(updates: Writable): void {
206-
updates.write(`I will run the following shell command: `)
207-
208-
if (this.command.length > 20) {
209-
updates.write('\n')
210-
}
211-
updates.write(`\x1b[32m${this.command}\x1b[0m\n`)
208+
updates.write(`I will run the following shell command:\n`)
209+
updates.write('```bash\n' + this.command + '\n```')
210+
updates.end()
212211
}
213212
}

0 commit comments

Comments
 (0)