@@ -32,6 +32,7 @@ import {
3232 DocumentReference ,
3333 FileClick ,
3434 RelevantTextDocumentAddition ,
35+ PromptInputOptionChange ,
3536} from './model'
3637import {
3738 AppToWebViewMessageDispatcher ,
@@ -82,9 +83,9 @@ import {
8283 createSavedPromptCommandId ,
8384 aditionalContentNameLimit ,
8485 additionalContentInnerContextLimit ,
85- tools ,
8686 workspaceChunkMaxSize ,
8787 defaultContextLengths ,
88+ noWriteTools ,
8889} from '../../constants'
8990import { ChatSession } from '../../clients/chat/v0/chat'
9091import { amazonQTabSuffix } from '../../../shared/constants'
@@ -118,6 +119,7 @@ export interface ChatControllerMessagePublishers {
118119 readonly processCustomFormAction : MessagePublisher < CustomFormActionMessage >
119120 readonly processContextSelected : MessagePublisher < ContextSelectedMessage >
120121 readonly processFileClick : MessagePublisher < FileClick >
122+ readonly processPromptInputOptionChange : MessagePublisher < PromptInputOptionChange >
121123}
122124
123125export interface ChatControllerMessageListeners {
@@ -143,6 +145,7 @@ export interface ChatControllerMessageListeners {
143145 readonly processCustomFormAction : MessageListener < CustomFormActionMessage >
144146 readonly processContextSelected : MessageListener < ContextSelectedMessage >
145147 readonly processFileClick : MessageListener < FileClick >
148+ readonly processPromptInputOptionChange : MessageListener < PromptInputOptionChange >
146149}
147150
148151export class ChatController {
@@ -278,6 +281,9 @@ export class ChatController {
278281 this . chatControllerMessageListeners . processFileClick . onMessage ( ( data ) => {
279282 return this . processFileClickMessage ( data )
280283 } )
284+ this . chatControllerMessageListeners . processPromptInputOptionChange . onMessage ( ( data ) => {
285+ return this . processPromptInputOptionChange ( data )
286+ } )
281287 }
282288
283289 private registerUserPromptsWatcher ( ) {
@@ -632,6 +638,70 @@ export class ChatController {
632638 telemetry . ui_click . emit ( { elementId : 'amazonq_createSavedPrompt' } )
633639 }
634640
641+ private async processUnavailableToolUseMessage ( message : CustomFormActionMessage ) {
642+ const tabID = message . tabID
643+ if ( ! tabID ) {
644+ return
645+ }
646+ this . editorContextExtractor
647+ . extractContextForTrigger ( 'ChatMessage' )
648+ . then ( async ( context ) => {
649+ const triggerID = randomUUID ( )
650+ this . triggerEventsStorage . addTriggerEvent ( {
651+ id : triggerID ,
652+ tabID : message . tabID ,
653+ message : undefined ,
654+ type : 'chat_message' ,
655+ context,
656+ } )
657+ const session = this . sessionStorage . getSession ( tabID )
658+ const toolUse = session . toolUse
659+ if ( ! toolUse || ! toolUse . input ) {
660+ return
661+ }
662+ session . setToolUse ( undefined )
663+
664+ const toolResults : ToolResult [ ] = [ ]
665+
666+ toolResults . push ( {
667+ content : [ { text : 'This tool is not an available tool in this mode' } ] ,
668+ toolUseId : toolUse . toolUseId ,
669+ status : ToolResultStatus . ERROR ,
670+ } )
671+
672+ await this . generateResponse (
673+ {
674+ message : '' ,
675+ trigger : ChatTriggerType . ChatMessage ,
676+ query : undefined ,
677+ codeSelection : context ?. focusAreaContext ?. selectionInsideExtendedCodeBlock ,
678+ fileText : context ?. focusAreaContext ?. extendedCodeBlock ?? '' ,
679+ fileLanguage : context ?. activeFileContext ?. fileLanguage ,
680+ filePath : context ?. activeFileContext ?. filePath ,
681+ matchPolicy : context ?. activeFileContext ?. matchPolicy ,
682+ codeQuery : context ?. focusAreaContext ?. names ,
683+ userIntent : undefined ,
684+ customization : getSelectedCustomization ( ) ,
685+ toolResults : toolResults ,
686+ origin : Origin . IDE ,
687+ chatHistory : this . chatHistoryStorage . getTabHistory ( tabID ) . getHistory ( ) ,
688+ context : session . context ?? [ ] ,
689+ relevantTextDocuments : [ ] ,
690+ additionalContents : [ ] ,
691+ documentReferences : [ ] ,
692+ useRelevantDocuments : false ,
693+ contextLengths : {
694+ ...defaultContextLengths ,
695+ } ,
696+ } ,
697+ triggerID
698+ )
699+ } )
700+ . catch ( ( e ) => {
701+ this . processException ( e , tabID )
702+ } )
703+ }
704+
635705 private async processToolUseMessage ( message : CustomFormActionMessage ) {
636706 const tabID = message . tabID
637707 if ( ! tabID ) {
@@ -764,6 +834,9 @@ export class ChatController {
764834 case 'reject-code-diff' :
765835 await this . closeDiffView ( )
766836 break
837+ case 'tool-unavailable' :
838+ await this . processUnavailableToolUseMessage ( message )
839+ break
767840 default :
768841 getLogger ( ) . warn ( `Unhandled action: ${ message . action . id } ` )
769842 }
@@ -774,6 +847,18 @@ export class ChatController {
774847 this . handlePromptCreate ( message . tabID )
775848 }
776849 }
850+
851+ private async processPromptInputOptionChange ( message : PromptInputOptionChange ) {
852+ const session = this . sessionStorage . getSession ( message . tabID )
853+ const promptTypeValue = message . optionsValues [ 'prompt-type' ]
854+ // TODO: display message: You turned off pair programmer mode. Q will not include code diffs or run commands in the chat.
855+ if ( promptTypeValue === 'pair-programming-on' ) {
856+ session . setPairProgrammingModeOn ( true )
857+ } else {
858+ session . setPairProgrammingModeOn ( false )
859+ }
860+ }
861+
777862 private async processFileClickMessage ( message : FileClick ) {
778863 const session = this . sessionStorage . getSession ( message . tabID )
779864 // Check if user clicked on filePath in the contextList or in the fileListTree and perform the functionality accordingly.
@@ -1354,25 +1439,18 @@ export class ChatController {
13541439
13551440 triggerPayload . contextLengths . userInputContextLength = triggerPayload . message . length
13561441 triggerPayload . contextLengths . focusFileContextLength = triggerPayload . fileText . length
1442+ triggerPayload . pairProgrammingModeOn = session . pairProgrammingModeOn
1443+
1444+ const request = triggerPayloadToChatRequest ( triggerPayload )
13571445
13581446 const chatHistory = this . chatHistoryStorage . getTabHistory ( tabID )
1359- const newUserMessage = {
1360- userInputMessage : {
1361- content : triggerPayload . message ,
1362- userIntent : triggerPayload . userIntent ,
1363- ...( triggerPayload . origin && { origin : triggerPayload . origin } ) ,
1364- userInputMessageContext : {
1365- tools : tools ,
1366- ...( triggerPayload . toolResults && { toolResults : triggerPayload . toolResults } ) ,
1367- } ,
1368- } ,
1369- }
1370- const fixedHistoryMessage = chatHistory . fixHistory ( newUserMessage )
1371- if ( fixedHistoryMessage . userInputMessage ?. userInputMessageContext ) {
1372- triggerPayload . toolResults = fixedHistoryMessage . userInputMessage . userInputMessageContext . toolResults
1447+ const currentMessage = request . conversationState . currentMessage
1448+ if ( currentMessage ) {
1449+ chatHistory . fixHistory ( currentMessage )
1450+
13731451 }
1374- triggerPayload . chatHistory = chatHistory . getHistory ( )
1375- const request = triggerPayloadToChatRequest ( triggerPayload )
1452+ request . conversationState . history = chatHistory . getHistory ( )
1453+
13761454 const conversationId = chatHistory . getConversationId ( ) || randomUUID ( )
13771455 chatHistory . setConversationId ( conversationId )
13781456 request . conversationState . conversationId = conversationId
@@ -1426,8 +1504,8 @@ export class ChatController {
14261504 }
14271505 this . telemetryHelper . recordEnterFocusConversation ( triggerEvent . tabID )
14281506 this . telemetryHelper . recordStartConversation ( triggerEvent , triggerPayload )
1429- if ( request . conversationState . currentMessage ) {
1430- chatHistory . appendUserMessage ( request . conversationState . currentMessage )
1507+ if ( currentMessage ) {
1508+ chatHistory . appendUserMessage ( currentMessage )
14311509 }
14321510
14331511 getLogger ( ) . info (
0 commit comments