Skip to content

Commit b2301fd

Browse files
authored
fix(amazonq): /doc Ask for user prompt if error occurs when user updates documentation (#5272)
1 parent 8006ae4 commit b2301fd

File tree

6 files changed

+86
-29
lines changed

6 files changed

+86
-29
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "bugfix",
3+
"description" : "Amazon Q /doc: Ask for user prompt if error occurs while updating documentation"
4+
}

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/DocConstants.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
package software.aws.toolkits.jetbrains.services.amazonqDoc
55

6+
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.FollowUp
7+
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.FollowUpStatusType
8+
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.FollowUpTypes
9+
import software.aws.toolkits.resources.message
10+
611
const val FEATURE_EVALUATION_PRODUCT_NAME = "DocGeneration"
712

813
const val FEATURE_NAME = "Amazon Q Documentation Generation"
@@ -25,3 +30,16 @@ enum class ModifySourceFolderErrorReason(
2530

2631
override fun toString(): String = reasonText
2732
}
33+
34+
val NEW_SESSION_FOLLOWUPS: List<FollowUp> = listOf(
35+
FollowUp(
36+
pillText = message("amazonqDoc.prompt.reject.new_task"),
37+
type = FollowUpTypes.NEW_TASK,
38+
status = FollowUpStatusType.Info
39+
),
40+
FollowUp(
41+
pillText = message("amazonqDoc.prompt.reject.close_session"),
42+
type = FollowUpTypes.CLOSE_SESSION,
43+
status = FollowUpStatusType.Info
44+
)
45+
)

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/DocExceptions.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@ package software.aws.toolkits.jetbrains.services.amazonqDoc
55

66
import software.aws.toolkits.resources.message
77

8-
open class DocException(override val message: String?, override val cause: Throwable? = null) : RuntimeException()
8+
open class DocException(
9+
override val message: String?,
10+
override val cause: Throwable? = null,
11+
val remainingIterations: Int? = null,
12+
) : RuntimeException()
913

1014
class ZipFileError(override val message: String, override val cause: Throwable?) : RuntimeException()
1115

1216
class CodeIterationLimitError(override val message: String, override val cause: Throwable?) : RuntimeException()
1317

14-
internal fun docServiceError(message: String?): Nothing =
15-
throw DocException(message)
16-
17-
internal fun codeGenerationFailedError(): Nothing =
18-
throw DocException(message("amazonqFeatureDev.code_generation.failed_generation"))
18+
internal fun docServiceError(message: String?, cause: Throwable? = null, remainingIterations: Int? = null): Nothing =
19+
throw DocException(message, cause, remainingIterations)
1920

2021
internal fun conversationIdNotFound(): Nothing =
2122
throw DocException(message("amazonqFeatureDev.exception.conversation_not_found"))

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/controller/DocController.kt

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendAuthenti
5353
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendChatInputEnabledMessage
5454
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendCodeResult
5555
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendError
56+
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendErrorToUser
5657
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendFolderConfirmationMessage
5758
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendMonthlyLimitError
5859
import software.aws.toolkits.jetbrains.services.amazonqDoc.messages.sendSystemPrompt
@@ -429,11 +430,10 @@ class DocController(
429430
messenger.sendUpdatePlaceholder(tabId, message("amazonqDoc.prompt.placeholder"))
430431
} catch (err: Exception) {
431432
val message = createUserFacingErrorMessage(err.message)
432-
messenger.sendError(
433+
messenger.sendErrorToUser(
433434
tabId = tabId,
434435
errMessage = message ?: message("amazonqFeatureDev.exception.request_failed"),
435-
retries = retriesRemaining(session),
436-
conversationId = session?.conversationIdUnsafe
436+
conversationId = session?.conversationIdUnsafe,
437437
)
438438
}
439439
}
@@ -555,7 +555,7 @@ class DocController(
555555
messenger.sendUpdatePlaceholder(tabId, message("amazonqFeatureDev.placeholder.provide_code_feedback"))
556556
}
557557

558-
private suspend fun processErrorChatMessage(err: Exception, session: DocSession?, tabId: String) {
558+
private suspend fun processErrorChatMessage(err: Exception, session: DocSession?, tabId: String, isEnableChatInput: Boolean) {
559559
logger.warn(err) { "Encountered ${err.message} for tabId: $tabId" }
560560
messenger.sendUpdatePromptProgress(tabId, null)
561561

@@ -595,23 +595,21 @@ class DocController(
595595
}
596596

597597
is DocException -> {
598-
messenger.sendError(
598+
messenger.sendErrorToUser(
599599
tabId = tabId,
600600
errMessage = err.message,
601-
retries = retriesRemaining(session),
602-
conversationId = session?.conversationIdUnsafe
601+
conversationId = session?.conversationIdUnsafe,
602+
isEnableChatInput
603603
)
604604
}
605605

606606
is CodeIterationLimitException -> {
607607
messenger.sendUpdatePlaceholder(tabId, newPlaceholder = message("amazonqFeatureDev.placeholder.after_monthly_limit"))
608608
messenger.sendChatInputEnabledMessage(tabId, enabled = true)
609-
messenger.sendError(
609+
messenger.sendErrorToUser(
610610
tabId = tabId,
611611
errMessage = err.message,
612-
retries = retriesRemaining(session),
613-
conversationId = session?.conversationIdUnsafe,
614-
showDefaultMessage = true,
612+
conversationId = session?.conversationIdUnsafe
615613
)
616614

617615
val filePaths: List<NewFileZipInfo> = when (val state = session?.sessionState) {
@@ -728,10 +726,13 @@ class DocController(
728726
)
729727
}
730728
} catch (err: Exception) {
731-
processErrorChatMessage(err, session, tabId)
729+
// For non edit mode lock the chat input until they explicitly click one of the follow-ups
730+
var isEnableChatInput = false
731+
if (err is DocException && Mode.EDIT == mode) {
732+
isEnableChatInput = err.remainingIterations != null && err.remainingIterations > 0
733+
}
732734

733-
// Lock the chat input until they explicitly click one of the follow-ups
734-
messenger.sendChatInputEnabledMessage(tabId, enabled = false)
735+
processErrorChatMessage(err, session, tabId, isEnableChatInput)
735736
}
736737
}
737738

@@ -811,10 +812,7 @@ class DocController(
811812
message = IncomingDocMessage.OpenDiff(tabId = followUpMessage.tabId, filePath = filePaths[0].zipFilePath, deleted = false)
812813
)
813814
} catch (err: Exception) {
814-
processErrorChatMessage(err, session, tabId = followUpMessage.tabId)
815-
816-
// Lock the chat input until they explicitly click one of the follow-ups
817-
messenger.sendChatInputEnabledMessage(tabId = followUpMessage.tabId, enabled = false)
815+
processErrorChatMessage(err, session, tabId = followUpMessage.tabId, false)
818816
} finally {
819817
messenger.sendUpdatePlaceholder(
820818
tabId = followUpMessage.tabId,

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/messages/DocMessagePublisherExtensions.kt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ import software.aws.toolkits.jetbrains.services.amazonq.auth.AuthNeededState
77
import software.aws.toolkits.jetbrains.services.amazonq.messages.MessagePublisher
88
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.ProgressField
99
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.PromptProgressMessage
10+
import software.aws.toolkits.jetbrains.services.amazonqDoc.NEW_SESSION_FOLLOWUPS
1011
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.CodeReferenceGenerated
1112
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.DeletedFileInfo
1213
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.NewFileZipInfo
1314
import software.aws.toolkits.jetbrains.services.cwc.messages.CodeReference
1415
import software.aws.toolkits.jetbrains.services.cwc.messages.RecommendationContentSpan
1516
import software.aws.toolkits.resources.message
17+
import java.util.Collections
1618
import java.util.UUID
1719

1820
suspend fun MessagePublisher.sendAnswer(
@@ -149,6 +151,39 @@ suspend fun MessagePublisher.sendError(tabId: String, errMessage: String?, retri
149151
)
150152
}
151153

154+
suspend fun MessagePublisher.sendErrorToUser(
155+
tabId: String,
156+
errMessage: String?,
157+
conversationId: String? = null,
158+
isEnableChatInput: Boolean = false,
159+
) {
160+
val conversationIdText = if (conversationId == null) "" else "\n\nConversation ID: **$conversationId**"
161+
162+
this.sendAnswer(
163+
tabId = tabId,
164+
messageType = DocMessageType.Answer,
165+
message = errMessage + conversationIdText,
166+
)
167+
168+
if (isEnableChatInput) {
169+
this.sendAnswer(
170+
tabId = tabId,
171+
messageType = DocMessageType.SystemPrompt,
172+
followUp = Collections.emptyList()
173+
)
174+
this.sendUpdatePlaceholder(tabId, message("amazonqDoc.edit.placeholder"))
175+
} else {
176+
this.sendAnswer(
177+
tabId = tabId,
178+
messageType = DocMessageType.SystemPrompt,
179+
followUp = NEW_SESSION_FOLLOWUPS
180+
)
181+
this.sendUpdatePlaceholder(tabId, message("amazonqDoc.prompt.placeholder"))
182+
}
183+
184+
this.sendChatInputEnabledMessage(tabId, enabled = isEnableChatInput)
185+
}
186+
152187
suspend fun MessagePublisher.sendMonthlyLimitError(tabId: String) {
153188
this.sendAnswer(
154189
tabId = tabId,

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/session/DocGenerationState.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,17 +172,18 @@ private suspend fun DocGenerationState.generateCode(codeGenerationId: String, mo
172172

173173
CodeGenerationWorkflowStatus.FAILED -> {
174174
messenger.sendUpdatePromptProgress(tabId = tabID, progressField = null)
175+
val remainingIterations = codeGenerationResultState.codeGenerationRemainingIterationCount()
175176

176177
when (true) {
177178
codeGenerationResultState.codeGenerationStatusDetail()?.contains(
178179
"README_TOO_LARGE"
179180
),
180-
-> docServiceError(message("amazonqDoc.exception.readme_too_large"))
181+
-> docServiceError(message("amazonqDoc.exception.readme_too_large"), remainingIterations = remainingIterations)
181182

182183
codeGenerationResultState.codeGenerationStatusDetail()?.contains(
183184
"README_UPDATE_TOO_LARGE"
184185
),
185-
-> docServiceError(message("amazonqDoc.exception.readme_update_too_large"))
186+
-> docServiceError(message("amazonqDoc.exception.readme_update_too_large"), remainingIterations = remainingIterations)
186187

187188
codeGenerationResultState.codeGenerationStatusDetail()?.contains(
188189
"WORKSPACE_TOO_LARGE"
@@ -197,17 +198,17 @@ private suspend fun DocGenerationState.generateCode(codeGenerationId: String, mo
197198
codeGenerationResultState.codeGenerationStatusDetail()?.contains(
198199
"PROMPT_UNRELATED"
199200
),
200-
-> docServiceError(message("amazonqDoc.exception.prompt_unrelated"))
201+
-> docServiceError(message("amazonqDoc.exception.prompt_unrelated"), remainingIterations = remainingIterations)
201202

202203
codeGenerationResultState.codeGenerationStatusDetail()?.contains(
203204
"PROMPT_TOO_VAGUE"
204205
),
205-
-> docServiceError(message("amazonqDoc.exception.prompt_too_vague"))
206+
-> docServiceError(message("amazonqDoc.exception.prompt_too_vague"), remainingIterations = remainingIterations)
206207

207208
codeGenerationResultState.codeGenerationStatusDetail()?.contains(
208209
"PromptRefusal"
209210
),
210-
-> docServiceError(message("amazonqFeatureDev.exception.prompt_refusal"))
211+
-> docServiceError(message("amazonqFeatureDev.exception.prompt_refusal"), remainingIterations = remainingIterations)
211212

212213
codeGenerationResultState.codeGenerationStatusDetail()?.contains(
213214
"Guardrails"

0 commit comments

Comments
 (0)