@@ -32,6 +32,7 @@ import {
32
32
DocumentReference ,
33
33
FileClick ,
34
34
RelevantTextDocumentAddition ,
35
+ PromptInputOptionChange ,
35
36
} from './model'
36
37
import {
37
38
AppToWebViewMessageDispatcher ,
@@ -117,6 +118,7 @@ export interface ChatControllerMessagePublishers {
117
118
readonly processCustomFormAction : MessagePublisher < CustomFormActionMessage >
118
119
readonly processContextSelected : MessagePublisher < ContextSelectedMessage >
119
120
readonly processFileClick : MessagePublisher < FileClick >
121
+ readonly processPromptInputOptionChange : MessagePublisher < PromptInputOptionChange >
120
122
}
121
123
122
124
export interface ChatControllerMessageListeners {
@@ -142,6 +144,7 @@ export interface ChatControllerMessageListeners {
142
144
readonly processCustomFormAction : MessageListener < CustomFormActionMessage >
143
145
readonly processContextSelected : MessageListener < ContextSelectedMessage >
144
146
readonly processFileClick : MessageListener < FileClick >
147
+ readonly processPromptInputOptionChange : MessageListener < PromptInputOptionChange >
145
148
}
146
149
147
150
export class ChatController {
@@ -277,6 +280,9 @@ export class ChatController {
277
280
this . chatControllerMessageListeners . processFileClick . onMessage ( ( data ) => {
278
281
return this . processFileClickMessage ( data )
279
282
} )
283
+ this . chatControllerMessageListeners . processPromptInputOptionChange . onMessage ( ( data ) => {
284
+ return this . processPromptInputOptionChange ( data )
285
+ } )
280
286
}
281
287
282
288
private registerUserPromptsWatcher ( ) {
@@ -631,6 +637,69 @@ export class ChatController {
631
637
telemetry . ui_click . emit ( { elementId : 'amazonq_createSavedPrompt' } )
632
638
}
633
639
640
+ private async processUnavailableToolUseMessage ( message : CustomFormActionMessage ) {
641
+ const tabID = message . tabID
642
+ if ( ! tabID ) {
643
+ return
644
+ }
645
+ this . editorContextExtractor
646
+ . extractContextForTrigger ( 'ChatMessage' )
647
+ . then ( async ( context ) => {
648
+ const triggerID = randomUUID ( )
649
+ this . triggerEventsStorage . addTriggerEvent ( {
650
+ id : triggerID ,
651
+ tabID : message . tabID ,
652
+ message : undefined ,
653
+ type : 'chat_message' ,
654
+ context,
655
+ } )
656
+ const session = this . sessionStorage . getSession ( tabID )
657
+ const toolUse = session . toolUse
658
+ if ( ! toolUse || ! toolUse . input ) {
659
+ return
660
+ }
661
+ session . setToolUse ( undefined )
662
+
663
+ const toolResults : ToolResult [ ] = [ ]
664
+
665
+ toolResults . push ( {
666
+ content : [ { text : 'This tool is not an available tool in this mode' } ] ,
667
+ toolUseId : toolUse . toolUseId ,
668
+ status : ToolResultStatus . ERROR ,
669
+ } )
670
+
671
+ await this . generateResponse (
672
+ {
673
+ message : '' ,
674
+ trigger : ChatTriggerType . ChatMessage ,
675
+ query : undefined ,
676
+ codeSelection : context ?. focusAreaContext ?. selectionInsideExtendedCodeBlock ,
677
+ fileText : context ?. focusAreaContext ?. extendedCodeBlock ?? '' ,
678
+ fileLanguage : context ?. activeFileContext ?. fileLanguage ,
679
+ filePath : context ?. activeFileContext ?. filePath ,
680
+ matchPolicy : context ?. activeFileContext ?. matchPolicy ,
681
+ codeQuery : context ?. focusAreaContext ?. names ,
682
+ userIntent : undefined ,
683
+ customization : getSelectedCustomization ( ) ,
684
+ toolResults : toolResults ,
685
+ origin : Origin . IDE ,
686
+ context : session . context ?? [ ] ,
687
+ relevantTextDocuments : [ ] ,
688
+ additionalContents : [ ] ,
689
+ documentReferences : [ ] ,
690
+ useRelevantDocuments : false ,
691
+ contextLengths : {
692
+ ...defaultContextLengths ,
693
+ } ,
694
+ } ,
695
+ triggerID
696
+ )
697
+ } )
698
+ . catch ( ( e ) => {
699
+ this . processException ( e , tabID )
700
+ } )
701
+ }
702
+
634
703
private async processToolUseMessage ( message : CustomFormActionMessage ) {
635
704
const tabID = message . tabID
636
705
if ( ! tabID ) {
@@ -763,6 +832,9 @@ export class ChatController {
763
832
case 'reject-code-diff' :
764
833
await this . closeDiffView ( )
765
834
break
835
+ case 'tool-unavailable' :
836
+ await this . processUnavailableToolUseMessage ( message )
837
+ break
766
838
default :
767
839
getLogger ( ) . warn ( `Unhandled action: ${ message . action . id } ` )
768
840
}
@@ -773,6 +845,18 @@ export class ChatController {
773
845
this . handlePromptCreate ( message . tabID )
774
846
}
775
847
}
848
+
849
+ private async processPromptInputOptionChange ( message : PromptInputOptionChange ) {
850
+ const session = this . sessionStorage . getSession ( message . tabID )
851
+ const promptTypeValue = message . optionsValues [ 'prompt-type' ]
852
+ // TODO: display message: You turned off pair programmer mode. Q will not include code diffs or run commands in the chat.
853
+ if ( promptTypeValue === 'pair-programming-on' ) {
854
+ session . setPairProgrammingModeOn ( true )
855
+ } else {
856
+ session . setPairProgrammingModeOn ( false )
857
+ }
858
+ }
859
+
776
860
private async processFileClickMessage ( message : FileClick ) {
777
861
const session = this . sessionStorage . getSession ( message . tabID )
778
862
// Check if user clicked on filePath in the contextList or in the fileListTree and perform the functionality accordingly.
@@ -1353,6 +1437,7 @@ export class ChatController {
1353
1437
1354
1438
triggerPayload . contextLengths . userInputContextLength = triggerPayload . message . length
1355
1439
triggerPayload . contextLengths . focusFileContextLength = triggerPayload . fileText . length
1440
+ triggerPayload . pairProgrammingModeOn = session . pairProgrammingModeOn
1356
1441
1357
1442
const request = triggerPayloadToChatRequest ( triggerPayload )
1358
1443
0 commit comments