@@ -675,70 +675,7 @@ export class ChatController {
675675 telemetry . ui_click . emit ( { elementId : 'amazonq_createSavedPrompt' } )
676676 }
677677
678- private async processUnavailableToolUseMessage ( message : CustomFormActionMessage ) {
679- const tabID = message . tabID
680- if ( ! tabID ) {
681- return
682- }
683- this . editorContextExtractor
684- . extractContextForTrigger ( 'ChatMessage' )
685- . then ( async ( context ) => {
686- const triggerID = randomUUID ( )
687- this . triggerEventsStorage . addTriggerEvent ( {
688- id : triggerID ,
689- tabID : message . tabID ,
690- message : undefined ,
691- type : 'chat_message' ,
692- context,
693- } )
694- const session = this . sessionStorage . getSession ( tabID )
695- const toolUse = session . toolUse
696- if ( ! toolUse || ! toolUse . input ) {
697- return
698- }
699- session . setToolUse ( undefined )
700-
701- const toolResults : ToolResult [ ] = [ ]
702-
703- toolResults . push ( {
704- content : [ { text : 'This tool is not an available tool in this mode' } ] ,
705- toolUseId : toolUse . toolUseId ,
706- status : ToolResultStatus . ERROR ,
707- } )
708-
709- await this . generateResponse (
710- {
711- message : '' ,
712- trigger : ChatTriggerType . ChatMessage ,
713- query : undefined ,
714- codeSelection : context ?. focusAreaContext ?. selectionInsideExtendedCodeBlock ,
715- fileText : context ?. focusAreaContext ?. extendedCodeBlock ?? '' ,
716- fileLanguage : context ?. activeFileContext ?. fileLanguage ,
717- filePath : context ?. activeFileContext ?. filePath ,
718- matchPolicy : context ?. activeFileContext ?. matchPolicy ,
719- codeQuery : context ?. focusAreaContext ?. names ,
720- userIntent : undefined ,
721- customization : getSelectedCustomization ( ) ,
722- toolResults : toolResults ,
723- origin : Origin . IDE ,
724- context : session . context ?? [ ] ,
725- relevantTextDocuments : [ ] ,
726- additionalContents : [ ] ,
727- documentReferences : [ ] ,
728- useRelevantDocuments : false ,
729- contextLengths : {
730- ...defaultContextLengths ,
731- } ,
732- } ,
733- triggerID
734- )
735- } )
736- . catch ( ( e ) => {
737- this . processException ( e , tabID )
738- } )
739- }
740-
741- private async processToolUseMessage ( message : CustomFormActionMessage ) {
678+ private async processToolUseMessage ( message : CustomFormActionMessage , isToolAvailable : boolean = true ) {
742679 const tabID = message . tabID
743680 if ( ! tabID ) {
744681 return
@@ -756,59 +693,75 @@ export class ChatController {
756693 } )
757694 this . messenger . sendAsyncEventProgress ( tabID , true , '' )
758695 const session = this . sessionStorage . getSession ( tabID )
759- const toolUse = session . toolUse
760- if ( ! toolUse || ! toolUse . input ) {
696+ const toolUseWithError = session . toolUseWithError
697+ if ( ! toolUseWithError || ! toolUseWithError . toolUse || ! toolUseWithError . toolUse . input ) {
761698 // Turn off AgentLoop flag if there's no tool use
762699 this . sessionStorage . setAgentLoopInProgress ( tabID , false )
763700 return
764701 }
765- session . setToolUse ( undefined )
702+ session . setToolUseWithError ( undefined )
766703
704+ const toolUse = toolUseWithError . toolUse
705+ const toolUseError = toolUseWithError . error
767706 const toolResults : ToolResult [ ] = [ ]
768707
769- const result = ToolUtils . tryFromToolUse ( toolUse )
770- if ( 'type' in result ) {
771- const tool : Tool = result
772-
773- try {
774- await ToolUtils . validate ( tool )
775-
776- const chatStream = new ChatStream ( this . messenger , tabID , triggerID , toolUse , {
777- requiresAcceptance : false ,
778- } )
779- const output = await ToolUtils . invoke ( tool , chatStream )
780- if ( output . output . content . length > maxToolOutputCharacterLength ) {
781- throw Error (
782- `Tool output exceeds maximum character limit of ${ maxToolOutputCharacterLength } `
783- )
708+ if ( toolUseError ) {
709+ toolResults . push ( {
710+ content : [ { text : toolUseError . message } ] ,
711+ toolUseId : toolUse . toolUseId ,
712+ status : ToolResultStatus . ERROR ,
713+ } )
714+ } else if ( ! isToolAvailable ) {
715+ toolResults . push ( {
716+ content : [ { text : 'This tool is not an available tool in this mode' } ] ,
717+ toolUseId : toolUseWithError . toolUse . toolUseId ,
718+ status : ToolResultStatus . ERROR ,
719+ } )
720+ } else {
721+ const result = ToolUtils . tryFromToolUse ( toolUse )
722+ if ( 'type' in result ) {
723+ const tool : Tool = result
724+
725+ try {
726+ await ToolUtils . validate ( tool )
727+
728+ const chatStream = new ChatStream ( this . messenger , tabID , triggerID , toolUse , {
729+ requiresAcceptance : false ,
730+ } )
731+ const output = await ToolUtils . invoke ( tool , chatStream )
732+ if ( output . output . content . length > maxToolOutputCharacterLength ) {
733+ throw Error (
734+ `Tool output exceeds maximum character limit of ${ maxToolOutputCharacterLength } `
735+ )
736+ }
737+
738+ toolResults . push ( {
739+ content : [
740+ output . output . kind === OutputKind . Text
741+ ? { text : output . output . content }
742+ : { json : output . output . content } ,
743+ ] ,
744+ toolUseId : toolUse . toolUseId ,
745+ status : ToolResultStatus . SUCCESS ,
746+ } )
747+ } catch ( e : any ) {
748+ toolResults . push ( {
749+ content : [ { text : e . message } ] ,
750+ toolUseId : toolUse . toolUseId ,
751+ status : ToolResultStatus . ERROR ,
752+ } )
784753 }
785-
786- toolResults . push ( {
787- content : [
788- output . output . kind === OutputKind . Text
789- ? { text : output . output . content }
790- : { json : output . output . content } ,
791- ] ,
792- toolUseId : toolUse . toolUseId ,
793- status : ToolResultStatus . SUCCESS ,
794- } )
795- } catch ( e : any ) {
796- toolResults . push ( {
797- content : [ { text : e . message } ] ,
798- toolUseId : toolUse . toolUseId ,
799- status : ToolResultStatus . ERROR ,
800- } )
754+ } else {
755+ const toolResult : ToolResult = result
756+ toolResults . push ( toolResult )
801757 }
802- } else {
803- const toolResult : ToolResult = result
804- toolResults . push ( toolResult )
805- }
806758
807- if ( toolUse . name === ToolType . FsWrite ) {
808- await vscode . commands . executeCommand (
809- 'vscode.open' ,
810- vscode . Uri . file ( ( toolUse . input as unknown as FsWriteParams ) . path )
811- )
759+ if ( toolUse . name === ToolType . FsWrite ) {
760+ await vscode . commands . executeCommand (
761+ 'vscode.open' ,
762+ vscode . Uri . file ( ( toolUse . input as unknown as FsWriteParams ) . path )
763+ )
764+ }
812765 }
813766
814767 await this . generateResponse (
@@ -880,7 +833,7 @@ export class ChatController {
880833 await this . rejectShellCommand ( message )
881834 break
882835 case 'tool-unavailable' :
883- await this . processUnavailableToolUseMessage ( message )
836+ await this . processToolUseMessage ( message , false )
884837 break
885838 default :
886839 getLogger ( ) . warn ( `Unhandled action: ${ message . action . id } ` )
@@ -920,19 +873,19 @@ export class ChatController {
920873 await fs . mkdir ( resultArtifactsDir )
921874 const tempFilePath = path . join (
922875 resultArtifactsDir ,
923- `temp-${ path . basename ( ( session . toolUse ? .input as unknown as FsWriteParams ) . path ) } `
876+ `temp-${ path . basename ( ( session . toolUseWithError ?. toolUse . input as unknown as FsWriteParams ) . path ) } `
924877 )
925878
926879 // If we have existing filePath copy file content from existing file to temporary file.
927- const filePath = ( session . toolUse ? .input as any ) . path ?? message . filePath
880+ const filePath = ( session . toolUseWithError ?. toolUse . input as any ) . path ?? message . filePath
928881 const fileExists = await fs . existsFile ( filePath )
929882 if ( fileExists ) {
930883 const fileContent = await fs . readFileText ( filePath )
931884 await fs . writeFile ( tempFilePath , fileContent )
932885 }
933886
934887 // Create a deep clone of the toolUse object and pass this toolUse to FsWrite tool execution to get the modified temporary file.
935- const clonedToolUse = structuredClone ( session . toolUse )
888+ const clonedToolUse = structuredClone ( session . toolUseWithError ?. toolUse )
936889 if ( ! clonedToolUse ) {
937890 return
938891 }
0 commit comments