Skip to content

Commit 3c67a95

Browse files
Merge branch 'feature/q-lsp-chat' into samgst/inline-completion-e2e
2 parents 104afe7 + 4b83365 commit 3c67a95

File tree

72 files changed

+901
-351
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+901
-351
lines changed

.changes/3.72.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"date" : "2025-05-22",
3+
"version" : "3.72",
4+
"entries" : [ {
5+
"type" : "removal",
6+
"description" : "/transform: remove option to receive multiple diffs"
7+
} ]
8+
}

.changes/3.73.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"date" : "2025-05-29",
3+
"version" : "3.73",
4+
"entries" : [ {
5+
"type" : "bugfix",
6+
"description" : "/transform: handle InvalidGrantException properly when polling job status"
7+
} ]
8+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "bugfix",
3+
"description" : "Support full Unicode range in inline chat panel on Windows"
4+
}

.changes/next-release/removal-dc421992-1194-47de-9908-930d70687453.json

Lines changed: 0 additions & 4 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# _3.73_ (2025-05-29)
2+
- **(Bug Fix)** /transform: handle InvalidGrantException properly when polling job status
3+
4+
# _3.72_ (2025-05-22)
5+
- **(Removal)** /transform: remove option to receive multiple diffs
6+
17
# _3.71_ (2025-05-15)
28
- **(Feature)** Add inline completion support for abap language
39
- **(Bug Fix)** Fix UI freezes that may occur when interacting with large files in the editor

buildspec/linuxTests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ phases:
4040
fi
4141
4242
- chmod +x gradlew
43-
- su codebuild-user -c "./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME check coverageReport --info --console plain --continue"
43+
- su codebuild-user -c "./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME check coverageReport --info --stacktrace --console plain --continue"
4444
- su codebuild-user -c "./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME buildPlugin"
4545
- VCS_COMMIT_ID="${CODEBUILD_RESOLVED_SOURCE_VERSION}"
4646
- CI_BUILD_URL=$(echo $CODEBUILD_BUILD_URL | sed 's/#/%23/g') # Encode `#` in the URL because otherwise the url is clipped in the Codecov.io site

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
# Toolkit Version
5-
toolkitVersion=3.72-SNAPSHOT
5+
toolkitVersion=3.74-SNAPSHOT
66

77
# Publish Settings
88
publishToken=

plugins/amazonq/build.gradle.kts

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType
4+
import com.fasterxml.jackson.databind.DeserializationFeature
5+
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
6+
import de.undercouch.gradle.tasks.download.Download
7+
import org.jetbrains.intellij.platform.gradle.tasks.PrepareSandboxTask
58
import software.aws.toolkits.gradle.changelog.tasks.GeneratePluginChangeLog
6-
import software.aws.toolkits.gradle.intellij.IdeFlavor
7-
import software.aws.toolkits.gradle.intellij.IdeVersions
8-
import software.aws.toolkits.gradle.intellij.toolkitIntelliJ
99

1010
plugins {
1111
id("toolkit-publishing-conventions")
1212
id("toolkit-publish-root-conventions")
1313
id("toolkit-jvm-conventions")
1414
id("toolkit-testing")
15+
id("de.undercouch.download")
16+
}
17+
18+
buildscript {
19+
dependencies {
20+
classpath(libs.bundles.jackson)
21+
}
1522
}
1623

1724
val changelog = tasks.register<GeneratePluginChangeLog>("pluginChangeLog") {
@@ -51,3 +58,81 @@ tasks.check {
5158
}
5259
}
5360
}
61+
62+
val downloadFlareManifest by tasks.registering(Download::class) {
63+
src("https://aws-toolkit-language-servers.amazonaws.com/qAgenticChatServer/0/manifest.json")
64+
dest(layout.buildDirectory.file("flare/manifest.json"))
65+
onlyIfModified(true)
66+
useETag(true)
67+
}
68+
69+
data class FlareManifest(
70+
val versions: List<FlareVersion>,
71+
)
72+
73+
data class FlareVersion(
74+
val serverVersion: String,
75+
val thirdPartyLicenses: String,
76+
val targets: List<FlareTarget>,
77+
)
78+
79+
data class FlareTarget(
80+
val platform: String,
81+
val arch: String,
82+
val contents: List<FlareContent>
83+
)
84+
85+
data class FlareContent(
86+
val url: String,
87+
)
88+
89+
val downloadFlareArtifacts by tasks.registering(Download::class) {
90+
dependsOn(downloadFlareManifest)
91+
inputs.files(downloadFlareManifest)
92+
93+
val manifestFile = downloadFlareManifest.map { it.outputFiles.first() }
94+
val manifest = manifestFile.map { jacksonObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).readValue(it.readText(), FlareManifest::class.java) }
95+
96+
// use darwin-aarch64 because its the smallest and we're going to throw away everything platform specific
97+
val latest = manifest.map { it.versions.first() }
98+
val latestVersion = latest.map { it.serverVersion }
99+
val licensesUrl = latest.map { it.thirdPartyLicenses }
100+
val darwin = latest.map { it.targets.first { target -> target.platform == "darwin" && target.arch == "arm64" } }
101+
val contentUrls = darwin.map { it.contents.map { content -> content.url } }
102+
103+
val destination = layout.buildDirectory.dir(latestVersion.map { "flare/$it" })
104+
outputs.dir(destination)
105+
106+
src(contentUrls.zip(licensesUrl) { left, right -> left + right})
107+
dest(destination)
108+
onlyIfModified(true)
109+
useETag(true)
110+
}
111+
112+
val prepareBundledFlare by tasks.registering(Copy::class) {
113+
dependsOn(downloadFlareArtifacts)
114+
inputs.files(downloadFlareArtifacts)
115+
116+
val dest = layout.buildDirectory.dir("tmp/extractFlare")
117+
into(dest)
118+
from(downloadFlareArtifacts.map { it.outputFiles.filterNot { file -> file.name.endsWith(".zip") } })
119+
120+
doLast {
121+
copy {
122+
into(dest)
123+
includeEmptyDirs = false
124+
downloadFlareArtifacts.get().outputFiles.filter { it.name.endsWith(".zip") }.forEach {
125+
dest.get().file(it.parentFile.name).asFile.createNewFile()
126+
from(zipTree(it)) {
127+
include("*.js")
128+
include("*.txt")
129+
}
130+
}
131+
}
132+
}
133+
}
134+
135+
tasks.withType<PrepareSandboxTask>().configureEach {
136+
intoChild(intellijPlatform.projectName.map { "$it/flare" })
137+
.from(prepareBundledFlare)
138+
}

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.JsonRpcNotification
4141
import software.aws.toolkits.jetbrains.services.amazonq.lsp.JsonRpcRequest
4242
import software.aws.toolkits.jetbrains.services.amazonq.lsp.encryption.JwtEncryptionManager
4343
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AwsServerCapabilitiesProvider
44+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.ChatAsyncResultManager
4445
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.ChatCommunicationManager
4546
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.FlareUiMessage
4647
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.AUTH_FOLLOW_UP_CLICKED
@@ -106,6 +107,7 @@ class BrowserConnector(
106107
) {
107108
var uiReady = CompletableDeferred<Boolean>()
108109
private val chatCommunicationManager = ChatCommunicationManager.getInstance(project)
110+
private val chatAsyncResultManager = ChatAsyncResultManager.getInstance(project)
109111

110112
suspend fun connect(
111113
browser: Browser,
@@ -227,6 +229,7 @@ class BrowserConnector(
227229

228230
val tabId = requestFromUi.params.tabId
229231
val partialResultToken = chatCommunicationManager.addPartialChatMessage(tabId)
232+
chatCommunicationManager.registerPartialResultToken(partialResultToken)
230233

231234
var encryptionManager: JwtEncryptionManager? = null
232235
val result = AmazonQLspService.executeIfRunning(project) { server ->
@@ -247,6 +250,7 @@ class BrowserConnector(
247250
val tabId = requestFromUi.params.tabId
248251
val quickActionParams = node.params ?: error("empty payload")
249252
val partialResultToken = chatCommunicationManager.addPartialChatMessage(tabId)
253+
chatCommunicationManager.registerPartialResultToken(partialResultToken)
250254
var encryptionManager: JwtEncryptionManager? = null
251255
val result = AmazonQLspService.executeIfRunning(project) { server ->
252256
encryptionManager = this.encryptionManager
@@ -476,15 +480,32 @@ class BrowserConnector(
476480
)
477481
browser.postChat(messageToChat)
478482
chatCommunicationManager.removeInflightRequestForTab(tabId)
479-
} catch (_: CancellationException) {
483+
} catch (e: CancellationException) {
480484
LOG.warn { "Cancelled chat generation" }
485+
try {
486+
chatAsyncResultManager.createRequestId(partialResultToken)
487+
chatAsyncResultManager.getResult(partialResultToken)
488+
handleCancellation(tabId, browser)
489+
} catch (ex: Exception) {
490+
LOG.warn(ex) { "An error occurred while processing cancellation" }
491+
} finally {
492+
chatAsyncResultManager.removeRequestId(partialResultToken)
493+
chatCommunicationManager.removePartialResultLock(partialResultToken)
494+
chatCommunicationManager.removeFinalResultProcessed(partialResultToken)
495+
}
481496
} catch (e: Exception) {
482-
LOG.error(e) { "Failed to send chat message" }
497+
LOG.warn(e) { "Failed to send chat message" }
483498
browser.postChat(chatCommunicationManager.getErrorUiMessage(tabId, e, partialResultToken))
484499
}
485500
}
486501
}
487502

503+
private fun handleCancellation(tabId: String, browser: Browser) {
504+
// Send a message to hide the stop button without showing an error
505+
val cancelMessage = chatCommunicationManager.getCancellationUiMessage(tabId)
506+
browser.postChat(cancelMessage)
507+
}
508+
488509
private fun cancelInflightRequests(tabId: String) {
489510
chatCommunicationManager.getInflightRequestForTab(tabId)?.let { request ->
490511
request.cancel(true)

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/theme/AmazonQTheme.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ data class AmazonQTheme(
1616
val defaultText: Color,
1717
val inactiveText: Color,
1818
val linkText: Color,
19+
val lightText: Color,
20+
val emptyText: Color,
1921

2022
val background: Color,
2123
val border: Color,
@@ -31,6 +33,8 @@ data class AmazonQTheme(
3133
val buttonBackground: Color,
3234
val secondaryButtonForeground: Color,
3335
val secondaryButtonBackground: Color,
36+
val inputBorderFocused: Color,
37+
val inputBorderUnfocused: Color,
3438

3539
val info: Color,
3640
val success: Color,

0 commit comments

Comments
 (0)