Skip to content

Commit

Permalink
fix(amazonq): /doc fix prompt to change folder in chat
Browse files Browse the repository at this point in the history
  • Loading branch information
Viktor Shesternyak committed Jan 10, 2025
1 parent b02e022 commit 2232d2d
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type" : "bugfix",
"description" : "Amazon Q /doc: fix for user prompt to change folder in chat"
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendCodeResu
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendError
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendFolderConfirmationMessage
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendMonthlyLimitError
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendRetryChangeFolderMessage
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendSystemPrompt
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendUpdatePlaceholder
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendUpdatePromptProgress
Expand Down Expand Up @@ -330,6 +331,83 @@ class DocController(
}
}

private suspend fun promptForRetryFolderSelection(tabId: String, message: String) {
try {
messenger.sendRetryChangeFolderMessage(
tabId = tabId,
message = message,
followUps = listOf(
FollowUp(
icon = FollowUpIcons.Refresh,
pillText = message("amazonqDoc.prompt.folder.change"),
prompt = message("amazonqDoc.prompt.folder.change"),
status = FollowUpStatusType.Info,
type = FollowUpTypes.MODIFY_DEFAULT_SOURCE_FOLDER
),
FollowUp(
icon = FollowUpIcons.Cancel,
pillText = message("general.cancel"),
prompt = message("general.cancel"),
status = FollowUpStatusType.Error,
type = FollowUpTypes.CANCEL_FOLDER_SELECTION
),
)
)

messenger.sendChatInputEnabledMessage(tabId, false)
} catch (e: Exception) {
logger.error(e) { "Error sending RetryChangeFolder message: ${e.message}" }
// Consider logging the error or handling it appropriately
}
}

override suspend fun processChatItemVotedMessage(message: IncomingDocMessage.ChatItemVotedMessage) {
logger.debug { "$FEATURE_NAME: Processing ChatItemVotedMessage: $message" }

val session = chatSessionStorage.getSession(message.tabId, context.project)
when (message.vote) {
"upvote" -> {
AmazonqTelemetry.codeGenerationThumbsUp(
amazonqConversationId = session.conversationId,
credentialStartUrl = getStartUrl(project = context.project)
)
}

"downvote" -> {
AmazonqTelemetry.codeGenerationThumbsDown(
amazonqConversationId = session.conversationId,
credentialStartUrl = getStartUrl(project = context.project)
)
}
}
}

override suspend fun processChatItemFeedbackMessage(message: IncomingDocMessage.ChatItemFeedbackMessage) {
logger.debug { "$FEATURE_NAME: Processing ChatItemFeedbackMessage: ${message.comment}" }

val session = getSessionInfo(message.tabId)

val comment = FeedbackComment(
conversationId = session.conversationId,
userComment = message.comment.orEmpty(),
reason = message.selectedOption,
messageId = message.messageId,
type = "doc-chat-answer-feedback"
)

try {
TelemetryService.getInstance().sendFeedback(
sentiment = Sentiment.NEGATIVE,
comment = objectMapper.writeValueAsString(comment),
)
logger.info { "$FEATURE_NAME answer feedback sent: \"Negative\"" }
} catch (e: Throwable) {
e.notifyError(message("feedback.submit_failed", e))
logger.warn(e) { "Failed to submit feedback" }
return
}
}

override suspend fun processLinkClick(message: IncomingDocMessage.ClickedLink) {
BrowserUtil.browse(message.link)
}
Expand Down Expand Up @@ -898,17 +976,21 @@ class DocController(
// No folder was selected
if (selectedFolder == null) {
logger.info { "Cancelled dialog and not selected any folder" }
promptForRetryFolderSelection(
tabId,
message("amazonqFeatureDev.follow_up.cancel_source_folder_selection")
)

return@withContext
}

// The folder is not in the workspace
if (!selectedFolder.path.startsWith(projectRoot.path)) {
logger.info { "Selected folder not in workspace: ${selectedFolder.path}" }

messenger.sendAnswer(
tabId = tabId,
messageType = DocMessageType.Answer,
message = message("amazonqFeatureDev.follow_up.incorrect_source_folder"),
promptForRetryFolderSelection(
tabId,
message("amazonqFeatureDev.follow_up.incorrect_source_folder")
)
return@withContext
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,15 @@ data class FolderConfirmationMessage(
type = "folderConfirmationMessage"
)

data class RetryChangeFolderMessage(
@JsonProperty("tabID") override val tabId: String,
val message: String,
val followUps: List<FollowUp>?,
) : UiMessage(
tabId = tabId,
type = "retryChangeFolderMessage"
)

// this should come from mynah?
data class ChatItemButton(
val id: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,16 @@ suspend fun MessagePublisher.sendFolderConfirmationMessage(
)
}

suspend fun MessagePublisher.sendRetryChangeFolderMessage(
tabId: String,
message: String,
followUps: List<FollowUp>,
) {
this.publish(
RetryChangeFolderMessage(tabId = tabId, message = message, followUps = followUps)
)
}

suspend fun MessagePublisher.sendUpdatePromptProgress(tabId: String, progressField: ProgressField?) {
this.publish(
PromptProgressMessage(tabId, progressField)
Expand Down
20 changes: 20 additions & 0 deletions plugins/amazonq/mynah-ui/src/mynah-ui/ui/apps/docChatConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@ export class Connector {
}
}

private processRetryChangeFolderMessage = async (messageData: any): Promise<void> => {
if (this.onChatAnswerReceived !== undefined) {
const answer: ChatItem = {
type: ChatItemType.ANSWER,
body: messageData.message ?? undefined,
messageId: messageData.messageID ?? messageData.triggerID ?? '',
followUp: {
text: '',
options: messageData.followUps,
},
}
this.onChatAnswerReceived(messageData.tabID, answer)
}
}

private processChatMessage = async (messageData: any): Promise<void> => {
if (this.onChatAnswerReceived !== undefined) {
const answer: ChatItem = {
Expand Down Expand Up @@ -263,6 +278,11 @@ export class Connector {
return
}

if (messageData.type === 'retryChangeFolderMessage') {
await this.processRetryChangeFolderMessage(messageData)
return
}

if (messageData.type === 'chatMessage') {
await this.processChatMessage(messageData)
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ amazonqFeatureDev.exception.throttling=I'm sorry, I'm experiencing high demand a
amazonqFeatureDev.exception.upload_code=I'm sorry, I couldn't upload your workspace artifacts to Amazon S3 to help you with this task. You might need to allow access to the S3 bucket. For more information, see the [Amazon Q documentation](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/security_iam_manage-access-with-policies.html#data-perimeters) or contact your network or organization administrator.
amazonqFeatureDev.exception.upload_url_expiry=I'm sorry, I wasn't able to generate code. A connection timed out or became unavailable. Please try again or check the following:\n\n- Exclude non-essential files in your workspace's `.gitignore`.\n\n- Check that your network connection is stable.
amazonqFeatureDev.follow_instructions_for_authentication=Follow instructions to re-authenticate ...
amazonqFeatureDev.follow_up.cancel_source_folder_selection=It looks like you didn't choose a folder. Choose a folder to continue.
amazonqFeatureDev.follow_up.close_session=No, thanks
amazonqFeatureDev.follow_up.continue=Continue
amazonqFeatureDev.follow_up.incorrect_source_folder=The folder you chose isn't in your open workspace folder. You can add this folder to your workspace, or choose a folder in your open workspace.
Expand Down

0 comments on commit 2232d2d

Please sign in to comment.