Skip to content
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
ba719b6
fix(amazonqFeatureDev): include stop generation
tverney Oct 3, 2024
153ddb8
fix(amazonqFeatureDev): add token for stop gen
tverney Oct 4, 2024
98aac91
Revert "fix(amazonqFeatureDev): include stop generation"
tverney Oct 4, 2024
dabd53c
Revert "Revert "fix(amazonqFeatureDev): include stop generation""
tverney Oct 4, 2024
67c231d
fix(amazonqFeatureDev): include cancellation token
tverney Oct 7, 2024
9150d7e
fix(amazonqFeatureDev): include defaults for empty string
tverney Oct 8, 2024
7f84621
telemetry(amazonq): add metrics for stop code generation
kelvin-klchu Oct 11, 2024
08367d4
fix(dev): messaging
tverney Oct 16, 2024
535cfc9
fix(dev): improve messaging
tverney Oct 16, 2024
5ee4abf
chore(dev): include changelog
tverney Oct 16, 2024
d43eb50
fix(dev): apply lint for build
tverney Oct 16, 2024
c080c6c
Merge branch 'main' into feature/stop-generation
tverney Oct 16, 2024
1877f34
fix(dev): update ident and unecessary safe type check
tverney Oct 16, 2024
446d5b2
Update CodeWhispererConstants.kt
tverney Oct 16, 2024
ccd5ebc
Merge branch 'main' into feature/stop-generation
tverney Oct 16, 2024
eb8cc1d
fix(dev): update tests
tverney Oct 16, 2024
aeeee4a
fix(dev): update tests
tverney Oct 16, 2024
6f99d90
fix(dev): use string instead of UUID in startAssist to help on testing
tverney Oct 16, 2024
42b9f81
fix(dev): update tests
tverney Oct 16, 2024
43b95de
Merge branch 'main' into feature/stop-generation
tverney Oct 16, 2024
6226c93
Merge branch 'main' into feature/stop-generation
tverney Oct 17, 2024
3220bbf
Updating version to 3.33
Oct 17, 2024
cfd2f5f
Updating SNAPSHOT version to 3.34-SNAPSHOT
Oct 17, 2024
7df34eb
refactor(amazonq): move codewhisperer utils/contants to amazonq/share…
Will-ShaoHua Oct 17, 2024
3f49129
refactor(amazonq): move CodeWhisperer FeatureConifgService, Settings …
Will-ShaoHua Oct 18, 2024
969fbda
refactor(amazonq): move projectContext folder to amazonq/shared (#4972)
Will-ShaoHua Oct 18, 2024
7a2116a
Fix broken Gateway / Rider profiles due to missing assets (#4984)
rli Oct 19, 2024
c323bb8
test(amazonq) fix broken FileContextProvider test (#4989)
Will-ShaoHua Oct 21, 2024
c38c01a
Merge branch 'main' into feature/stop-generation
tverney Oct 21, 2024
1234c76
Merge branch 'main' into feature/stop-generation
tverney Oct 22, 2024
290ed7d
fix(dev): update formatting
tverney Oct 22, 2024
34c42b9
fix(dev): use currentIteration since the counts isnt provided when st…
tverney Oct 22, 2024
68a37f2
fix(dev): update formatting
tverney Oct 22, 2024
71b03d7
Merge branch 'main' into feature/stop-generation
tverney Oct 23, 2024
1e96798
Delete package-lock.json
tverney Oct 23, 2024
97c760b
Update plugins/amazonq/chat/jetbrains-community/src/software/aws/tool…
tverney Oct 23, 2024
565244a
fix(dev): remove disposeToken as plugin
tverney Oct 23, 2024
1d04af9
fix(dev): revert lazy log file per request
tverney Oct 23, 2024
a7477aa
fix(dev): remove redundant reassign
tverney Oct 23, 2024
be9f818
Update plugins/amazonq/chat/jetbrains-community/src/software/aws/tool…
tverney Oct 23, 2024
41f0403
fix(dev): change number to int for iterations number
tverney Oct 23, 2024
914b140
fix(dev): use val instead
tverney Oct 23, 2024
c17a0f1
fix(dev): replace gradle dependency for our own cancellation token
tverney Oct 23, 2024
d84a9e2
fix(dev): removed gradle and added our own cancellation token
tverney Oct 23, 2024
ae7f9c6
Merge branch 'main' into feature/stop-generation
tverney Oct 23, 2024
d11f7e2
telemetry(amazonq): replace stopCodeGeneration telemetry with UiTelem…
kelvin-klchu Oct 11, 2024
2eea363
Merge pull request #2 from kelvin-klchu/stop-code-gen-telemetry
tverney Oct 23, 2024
2374e67
fix(dev): remove todo section
tverney Oct 23, 2024
abf8f43
fix(dev): add it back cwc on stop chat response
tverney Oct 23, 2024
538eb00
fix build error
rli Oct 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type" : "feature",
"description" : "Amazon Q /dev: Add stop generation action"
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ class FeatureDevApp : AmazonQApp {
"response-body-link-click" to IncomingFeatureDevMessage.ClickedLink::class,
"insert_code_at_cursor_position" to IncomingFeatureDevMessage.InsertCodeAtCursorPosition::class,
"open-diff" to IncomingFeatureDevMessage.OpenDiff::class,
"file-click" to IncomingFeatureDevMessage.FileClicked::class
"file-click" to IncomingFeatureDevMessage.FileClicked::class,
"stop-response" to IncomingFeatureDevMessage.StopResponse::class
)

scope.launch {
Expand Down Expand Up @@ -82,6 +83,7 @@ class FeatureDevApp : AmazonQApp {
is IncomingFeatureDevMessage.InsertCodeAtCursorPosition -> inboundAppMessagesHandler.processInsertCodeAtCursorPosition(message)
is IncomingFeatureDevMessage.OpenDiff -> inboundAppMessagesHandler.processOpenDiff(message)
is IncomingFeatureDevMessage.FileClicked -> inboundAppMessagesHandler.processFileClicked(message)
is IncomingFeatureDevMessage.StopResponse -> inboundAppMessagesHandler.processStopMessage(message)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ interface InboundAppMessagesHandler {
suspend fun processInsertCodeAtCursorPosition(message: IncomingFeatureDevMessage.InsertCodeAtCursorPosition)
suspend fun processOpenDiff(message: IncomingFeatureDevMessage.OpenDiff)
suspend fun processFileClicked(message: IncomingFeatureDevMessage.FileClicked)
suspend fun processStopMessage(message: IncomingFeatureDevMessage.StopResponse)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please avoid unnecessary whitespace changes in PRs with substantial content to review. they should be done separately for ease of review

Original file line number Diff line number Diff line change
Expand Up @@ -39,107 +39,135 @@ import java.time.Instant
import software.amazon.awssdk.services.codewhispererruntime.model.ChatTriggerType as SyncChatTriggerType

@Service(Service.Level.PROJECT)
class FeatureDevClient(private val project: Project) {
class FeatureDevClient(
private val project: Project,
) {
fun getTelemetryOptOutPreference() =
if (AwsSettings.getInstance().isTelemetryEnabled) {
OptOutPreference.OPTIN
} else {
OptOutPreference.OPTOUT
}

private val featureDevUserContext = ClientMetadata.getDefault().let {
val osForFeatureDev: OperatingSystem =
when {
SystemInfo.isWindows -> OperatingSystem.WINDOWS
SystemInfo.isMac -> OperatingSystem.MAC
// For now, categorize everything else as "Linux" (Linux/FreeBSD/Solaris/etc.)
else -> OperatingSystem.LINUX
}
private val featureDevUserContext =
ClientMetadata.getDefault().let {
val osForFeatureDev: OperatingSystem =
when {
SystemInfo.isWindows -> OperatingSystem.WINDOWS
SystemInfo.isMac -> OperatingSystem.MAC
// For now, categorize everything else as "Linux" (Linux/FreeBSD/Solaris/etc.)
else -> OperatingSystem.LINUX
}

UserContext.builder()
.ideCategory(IdeCategory.JETBRAINS)
.operatingSystem(osForFeatureDev)
.product(FEATURE_EVALUATION_PRODUCT_NAME)
.clientId(it.clientId)
.ideVersion(it.awsVersion)
.build()
}
UserContext
.builder()
.ideCategory(IdeCategory.JETBRAINS)
.operatingSystem(osForFeatureDev)
.product(FEATURE_EVALUATION_PRODUCT_NAME)
.clientId(it.clientId)
.ideVersion(it.awsVersion)
.build()
}

private fun connection() = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(QConnection.getInstance())
?: error("Attempted to use connection while one does not exist")
private fun connection() =
ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(QConnection.getInstance())
?: error("Attempted to use connection while one does not exist")

private fun bearerClient() = connection().getConnectionSettings().awsClient<CodeWhispererRuntimeClient>()

private val amazonQStreamingClient
get() = AmazonQStreamingClient.getInstance(project)

fun sendFeatureDevTelemetryEvent(conversationId: String): SendTelemetryEventResponse = bearerClient().sendTelemetryEvent { requestBuilder ->
requestBuilder.telemetryEvent { telemetryEventBuilder ->
telemetryEventBuilder.featureDevEvent {
it.conversationId(conversationId)
fun sendFeatureDevTelemetryEvent(conversationId: String): SendTelemetryEventResponse =
bearerClient().sendTelemetryEvent { requestBuilder ->
requestBuilder.telemetryEvent { telemetryEventBuilder ->
telemetryEventBuilder.featureDevEvent {
it.conversationId(conversationId)
}
}
requestBuilder.optOutPreference(getTelemetryOptOutPreference())
requestBuilder.userContext(featureDevUserContext)
}
requestBuilder.optOutPreference(getTelemetryOptOutPreference())
requestBuilder.userContext(featureDevUserContext)
}

fun createTaskAssistConversation(): CreateTaskAssistConversationResponse = bearerClient().createTaskAssistConversation(
CreateTaskAssistConversationRequest.builder().build()
)

fun createTaskAssistUploadUrl(conversationId: String, contentChecksumSha256: String, contentLength: Long): CreateUploadUrlResponse =
fun createTaskAssistConversation(): CreateTaskAssistConversationResponse =
bearerClient().createTaskAssistConversation(
CreateTaskAssistConversationRequest.builder().build(),
)

fun createTaskAssistUploadUrl(
conversationId: String,
contentChecksumSha256: String,
contentLength: Long,
uploadId: String,
): CreateUploadUrlResponse =
bearerClient().createUploadUrl {
it.contentChecksumType(ContentChecksumType.SHA_256)
it
.contentChecksumType(ContentChecksumType.SHA_256)
.uploadId(uploadId)
.contentChecksum(contentChecksumSha256)
.contentLength(contentLength)
.artifactType(ArtifactType.SOURCE_CODE)
.uploadIntent(UploadIntent.TASK_ASSIST_PLANNING)
.uploadContext(
UploadContext.builder()
UploadContext
.builder()
.taskAssistPlanningUploadContext(
TaskAssistPlanningUploadContext.builder()
TaskAssistPlanningUploadContext
.builder()
.conversationId(conversationId)
.build()
)
.build()
.build(),
).build(),
)
}

fun startTaskAssistCodeGeneration(conversationId: String, uploadId: String, userMessage: String): StartTaskAssistCodeGenerationResponse = bearerClient()
.startTaskAssistCodeGeneration {
request ->
request
.conversationState {
it
.conversationId(conversationId)
.chatTriggerType(SyncChatTriggerType.MANUAL)
.currentMessage { cm -> cm.userInputMessage { um -> um.content(userMessage) } }
}
.workspaceState {
it
.programmingLanguage { pl -> pl.languageName("javascript") } // This parameter is omitted by featureDev but required in the request
.uploadId(uploadId)
}
}
fun startTaskAssistCodeGeneration(
conversationId: String,
uploadId: String,
userMessage: String,
codeGenerationId: String?,
currentCodeGenerationId: String?,
): StartTaskAssistCodeGenerationResponse =
bearerClient()
.startTaskAssistCodeGeneration { request ->
request
.conversationState {
it
.conversationId(conversationId)
.chatTriggerType(SyncChatTriggerType.MANUAL)
.currentMessage { cm -> cm.userInputMessage { um -> um.content(userMessage) } }
}.workspaceState {
it
.programmingLanguage { pl -> pl.languageName("javascript") } // This parameter is omitted by featureDev but required in the request
.uploadId(uploadId)
}.codeGenerationId(codeGenerationId.toString())
.currentCodeGenerationId(currentCodeGenerationId)
}

fun getTaskAssistCodeGeneration(conversationId: String, codeGenerationId: String): GetTaskAssistCodeGenerationResponse = bearerClient()
.getTaskAssistCodeGeneration {
it
.conversationId(conversationId)
.codeGenerationId(codeGenerationId)
}
fun getTaskAssistCodeGeneration(
conversationId: String,
codeGenerationId: String,
): GetTaskAssistCodeGenerationResponse =
bearerClient()
.getTaskAssistCodeGeneration {
it
.conversationId(conversationId)
.codeGenerationId(codeGenerationId)
}

suspend fun exportTaskAssistResultArchive(conversationId: String): MutableList<ByteArray> = amazonQStreamingClient.exportResultArchive(
conversationId,
ExportIntent.TASK_ASSIST,
null,
{ e ->
LOG.error(e) { "TaskAssist - ExportResultArchive stream exportId=$conversationId exportIntent=${ExportIntent.TASK_ASSIST} Failed: ${e.message} " }
},
{ startTime ->
LOG.info { "TaskAssist - ExportResultArchive latency: ${calculateTotalLatency(startTime, Instant.now())}" }
}
)
suspend fun exportTaskAssistResultArchive(conversationId: String): MutableList<ByteArray> =
amazonQStreamingClient.exportResultArchive(
conversationId,
ExportIntent.TASK_ASSIST,
null,
{ e ->
LOG.error(
e,
) { "TaskAssist - ExportResultArchive stream exportId=$conversationId exportIntent=${ExportIntent.TASK_ASSIST} Failed: ${e.message} " }
},
{ startTime ->
LOG.info { "TaskAssist - ExportResultArchive latency: ${calculateTotalLatency(startTime, Instant.now())}" }
},
)

companion object {
private val LOG = getLogger<FeatureDevClient>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.intellij.openapi.editor.Caret
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.wm.ToolWindowManager
import kotlinx.coroutines.withContext
Expand Down Expand Up @@ -74,6 +75,7 @@
import software.aws.toolkits.resources.message
import software.aws.toolkits.telemetry.AmazonqTelemetry
import software.aws.toolkits.telemetry.Result
import software.aws.toolkits.telemetry.UiTelemetry
import java.util.UUID

class FeatureDevController(
Expand All @@ -92,6 +94,10 @@
)
}

override suspend fun processStopMessage(message: IncomingFeatureDevMessage.StopResponse) {
handleStopMessage(message)
}

override suspend fun processNewTabCreatedMessage(message: IncomingFeatureDevMessage.NewTabCreated) {
newTabOpened(message.tabId)
}
Expand Down Expand Up @@ -284,6 +290,26 @@
}
}

private suspend fun handleStopMessage(message: IncomingFeatureDevMessage.StopResponse) {
val session: Session?
UiTelemetry.click(null as Project?, "amazonq_stopCodeGeneration")
messenger.sendAnswer(
tabId = message.tabId,
message("amazonqFeatureDev.code_generation.stopping_code_generation"),
messageType = FeatureDevMessageType.Answer,
canBeVoted = false
)
messenger.sendUpdatePlaceholder(
tabId = message.tabId,
newPlaceholder = message("amazonqFeatureDev.code_generation.stopping_code_generation")
)
messenger.sendChatInputEnabledMessage(tabId = message.tabId, enabled = false)
session = getSessionInfo(message.tabId)

if (session.sessionState.token?.token !== null) {
session.sessionState.token?.cancel()
}
}
private suspend fun insertCode(tabId: String) {
var session: Session? = null
try {
Expand Down Expand Up @@ -330,7 +356,7 @@
status = FollowUpStatusType.Info
),
FollowUp(
pillText = message("amazonqFeatureDev.follow_up.close_session"),

Check warning on line 359 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/controller/FeatureDevController.kt

View workflow job for this annotation

GitHub Actions / qodana

Usage of redundant or deprecated syntax or deprecated symbols

'message(String, vararg Any): String' is deprecated. Use extension-specific localization bundle instead
type = FollowUpTypes.CLOSE_SESSION,
status = FollowUpStatusType.Info
)
Expand Down Expand Up @@ -647,7 +673,7 @@
messenger.sendAnswer(
tabId = tabId,
messageType = FeatureDevMessageType.Answer,
message = message("amazonqFeatureDev.follow_up.modified_source_folder", selectedFolder.path),

Check warning on line 676 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/controller/FeatureDevController.kt

View workflow job for this annotation

GitHub Actions / qodana

Usage of redundant or deprecated syntax or deprecated symbols

'message(String, vararg Any): String' is deprecated. Use extension-specific localization bundle instead
canBeVoted = true,
)

Expand Down
Loading
Loading