Skip to content

Commit

Permalink
Determine and send inline completion session result (#323)
Browse files Browse the repository at this point in the history
  • Loading branch information
shruti0085 authored Jan 15, 2025
1 parent 9d818a8 commit faa503e
Show file tree
Hide file tree
Showing 9 changed files with 344 additions and 28 deletions.
3 changes: 2 additions & 1 deletion plugin/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.31.0",
org.eclipse.jetty.util;bundle-version="12.0.9",
org.eclipse.core.net;bundle-version="1.5.400",
org.apache.commons.logging;bundle-version="1.2.0",
slf4j.api;bundle-version="2.0.13"
slf4j.api;bundle-version="2.0.13",
org.apache.commons.lang3;bundle-version="3.14.0"
Bundle-Classpath: target/classes/,
target/dependency/annotations-2.28.26.jar,
target/dependency/apache-client-2.28.26.jar,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public final synchronized Object execute(final ExecutionEvent event) throws Exec
var suggestion = QInvocationSession.getInstance().getCurrentSuggestion();
var widget = QInvocationSession.getInstance().getViewer().getTextWidget();
var session = QInvocationSession.getInstance();
// mark current suggestion as accepted
session.setAccepted(suggestion.getItemId());
session.setSuggestionAccepted(true);
session.transitionToDecisionMade();
Display display = widget.getDisplay();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import software.aws.toolkits.eclipse.amazonq.lsp.model.GetConfigurationFromServerParams;
import software.aws.toolkits.eclipse.amazonq.lsp.model.InlineCompletionParams;
import software.aws.toolkits.eclipse.amazonq.lsp.model.InlineCompletionResponse;
import software.aws.toolkits.eclipse.amazonq.lsp.model.LogInlineCompletionSessionResultsParams;
import software.aws.toolkits.eclipse.amazonq.lsp.model.LspServerConfigurations;
import software.aws.toolkits.eclipse.amazonq.lsp.model.UpdateCredentialsPayload;

Expand All @@ -30,6 +31,9 @@ public interface AmazonQLspServer extends LanguageServer {
@JsonRequest("aws/textDocument/inlineCompletionWithReferences")
CompletableFuture<InlineCompletionResponse> inlineCompletionWithReferences(InlineCompletionParams params);

@JsonNotification("aws/logInlineCompletionSessionResults")
void logInlineCompletionSessionResult(LogInlineCompletionSessionResultsParams params);

@JsonRequest("aws/chat/sendChatPrompt")
CompletableFuture<String> sendChatPrompt(EncryptedChatParams encryptedChatRequestParams);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.eclipse.amazonq.lsp.model;

public final class InlineCompletionStates {
// Indicates if suggestion has been seen by the user in the UI
private boolean seen;
// Indicates if suggestion accepted
private boolean accepted;
// Indicates if suggestion was filtered out on the client-side and marked as
// discarded.
private boolean discarded;

public boolean isSeen() {
return seen;
}

public void setSeen(final boolean seen) {
this.seen = seen;
}

public boolean isAccepted() {
return accepted;
}

public void setAccepted(final boolean accepted) {
this.accepted = accepted;
}

public boolean isDiscarded() {
return discarded;
}

public void setDiscarded(final boolean discarded) {
this.discarded = discarded;
}

@Override
public String toString() {
return String.format("{accepted=%b, seen=%b, discarded=%b}", accepted, seen, discarded);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.eclipse.amazonq.lsp.model;

import java.util.concurrent.ConcurrentHashMap;

import com.fasterxml.jackson.annotation.JsonInclude;

public final class LogInlineCompletionSessionResultsParams {
// Session Id attached to get completion items response
private final String sessionId;
// Map with results of interaction with completion items/suggestions in the UI
private final ConcurrentHashMap<String, InlineCompletionStates> completionSessionResult;

// Total time when items from this suggestion session were visible in UI
@JsonInclude(JsonInclude.Include.NON_NULL)
private Long totalSessionDisplayTime;
// Time from request invocation start to rendering of the first suggestion in the UI.
@JsonInclude(JsonInclude.Include.NON_NULL)
private Long firstCompletionDisplayLatency;
// Length of additional characters inputed by user from when the trigger happens to when the first suggestion is about to be shown in UI
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer typeaheadLength;

public LogInlineCompletionSessionResultsParams(final String sessionId, final ConcurrentHashMap<String, InlineCompletionStates> completionSessionResult) {
this.sessionId = sessionId;
this.completionSessionResult = completionSessionResult;
}

public Long getTotalSessionDisplayTime() {
return totalSessionDisplayTime;
}

public void setTotalSessionDisplayTime(final Long totalSessionDisplayTime) {
this.totalSessionDisplayTime = totalSessionDisplayTime;
}

public Long getFirstCompletionDisplayLatency() {
return firstCompletionDisplayLatency;
}

public void setFirstCompletionDisplayLatency(final Long firstCompletionDisplayLatency) {
this.firstCompletionDisplayLatency = firstCompletionDisplayLatency;
}

public Integer getTypeaheadLength() {
return typeaheadLength;
}

public void setTypeaheadLength(final Integer typeaheadLength) {
this.typeaheadLength = typeaheadLength;
}

public ConcurrentHashMap<String, InlineCompletionStates> getCompletionSessionResult() {
return completionSessionResult;
}

public String getSessionId() {
return sessionId;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -274,18 +274,33 @@ public void documentChanged(final DocumentEvent event) {
}
String currentSuggestion = session.getCurrentSuggestion().getInsertText();
int currentOffset = widget.getCaretOffset();

if (input.isEmpty()) {
if (distanceTraversed <= 0) {
// discard all suggestions as caret position is less than request invocation position
session.updateCompletionStates(new ArrayList<String>());
session.transitionToDecisionMade();
session.end();
return;
}
distanceTraversed = typeaheadProcessor.getNewDistanceTraversedOnDeleteAndUpdateBracketState(
event.getLength(), distanceTraversed, brackets);
if (distanceTraversed < 0) {
// discard all suggestions as caret position is less than request invocation position
session.updateCompletionStates(new ArrayList<String>());
session.transitionToDecisionMade();
session.end();
}

// note: distanceTraversed as 0 is currently understood to be when a user presses BS removing any typeahead
if (distanceTraversed == 0) {
// reset completion states for all suggestions when user reverts to request
// invocation state
session.resetCompletionStates();
// mark currently displayed suggestion as seen
session.markSuggestionAsSeen();
}

return;
}

Expand Down Expand Up @@ -328,12 +343,19 @@ public void documentChanged(final DocumentEvent event) {
session.transitionToDecisionMade(lineToUnsetIndent);
Display.getCurrent().asyncExec(() -> {
if (session.isActive()) {
session.end();
// discard suggestions and end immediately as typeahead does not match
session.updateCompletionStates(new ArrayList<String>());
session.endImmediately();
}
});
return;
}

// discard all other suggestions except for current one as typeahead matches it
// also mark current one as seen as it continues to be displayed
session.updateCompletionStates(List.of(session.getCurrentSuggestion().getItemId()));
session.markSuggestionAsSeen();

// Here we perform "post closing bracket insertion caret correction", which
// consists of the following:
// - Check if the input is a closing bracket
Expand Down Expand Up @@ -398,7 +420,7 @@ public void mouseDown(final MouseEvent e) {
int currentOffset = invocationOffset + distanceTraversed;
int lastKnownLine = widget.getLineAtOffset(currentOffset);
qInvocationSessionInstance.transitionToDecisionMade(lastKnownLine + 1);
qInvocationSessionInstance.end();
qInvocationSessionInstance.endImmediately();
return;
}

Expand Down
Loading

0 comments on commit faa503e

Please sign in to comment.