mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-20 01:02:02 +00:00
fix: build errors
This commit is contained in:
parent
15d3423d92
commit
e26034367e
7 changed files with 19 additions and 188 deletions
|
|
@ -23,13 +23,13 @@ class CodeCompletionEventListener implements CompletionEventListener<String> {
|
|||
|
||||
private final Editor editor;
|
||||
private final int caretOffset;
|
||||
private final InfillRequestDetails requestDetails;
|
||||
private final InfillRequest requestDetails;
|
||||
private final BackgroundableProcessIndicator progressIndicator;
|
||||
|
||||
public CodeCompletionEventListener(
|
||||
Editor editor,
|
||||
int caretOffset,
|
||||
InfillRequestDetails requestDetails,
|
||||
InfillRequest requestDetails,
|
||||
@Nullable BackgroundableProcessIndicator progressIndicator) {
|
||||
this.editor = editor;
|
||||
this.caretOffset = caretOffset;
|
||||
|
|
|
|||
|
|
@ -9,15 +9,15 @@ public class CodeCompletionRequestProvider {
|
|||
|
||||
private static final int MAX_TOKENS = 128;
|
||||
|
||||
private final InfillRequestDetails details;
|
||||
private final InfillRequest request;
|
||||
|
||||
public CodeCompletionRequestProvider(InfillRequestDetails details) {
|
||||
this.details = details;
|
||||
public CodeCompletionRequestProvider(InfillRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public OpenAITextCompletionRequest buildOpenAIRequest() {
|
||||
return new OpenAITextCompletionRequest.Builder(details.getPrefix())
|
||||
.setSuffix(details.getSuffix())
|
||||
return new OpenAITextCompletionRequest.Builder(request.getPrefix())
|
||||
.setSuffix(request.getSuffix())
|
||||
.setStream(true)
|
||||
.setMaxTokens(MAX_TOKENS)
|
||||
.setTemperature(0.1)
|
||||
|
|
@ -26,8 +26,7 @@ public class CodeCompletionRequestProvider {
|
|||
|
||||
public LlamaCompletionRequest buildLlamaRequest() {
|
||||
InfillPromptTemplate promptTemplate = getLlamaInfillPromptTemplate();
|
||||
String prompt = promptTemplate.buildPrompt(
|
||||
new InfillRequestDetails(details.getPrefix(), details.getSuffix(), null));
|
||||
String prompt = promptTemplate.buildPrompt(request);
|
||||
return new LlamaCompletionRequest.Builder(prompt)
|
||||
.setN_predict(MAX_TOKENS)
|
||||
.setStream(true)
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ public final class CodeCompletionServiceOld implements Disposable {
|
|||
var prefix = document.getText(new TextRange(0, offset));
|
||||
var suffix = document.getText(new TextRange(offset, document.getTextLength()));
|
||||
|
||||
var request = InfillRequestDetails.Companion.withoutContext(prefix, suffix);
|
||||
var request = InfillRequest.Companion.builder(prefix, suffix).build();
|
||||
if (Stream.of(request.getSuffix(), request.getPrefix()).anyMatch(String::isEmpty)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.intellij.openapi.components.Service;
|
|||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory;
|
||||
import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestProvider;
|
||||
import ee.carlrobert.codegpt.codecompletions.InfillRequestDetails;
|
||||
import ee.carlrobert.codegpt.codecompletions.InfillRequest;
|
||||
import ee.carlrobert.codegpt.completions.llama.LlamaModel;
|
||||
import ee.carlrobert.codegpt.completions.llama.PromptTemplate;
|
||||
import ee.carlrobert.codegpt.credentials.CredentialsStore;
|
||||
|
|
@ -133,13 +133,13 @@ public final class CompletionRequestService {
|
|||
}
|
||||
|
||||
public EventSource getCodeCompletionAsync(
|
||||
InfillRequestDetails requestDetails,
|
||||
InfillRequest requestDetails,
|
||||
CompletionEventListener<String> eventListener) {
|
||||
var httpClient = CompletionClientProvider.getDefaultClientBuilder().build();
|
||||
var requestProvider = new CodeCompletionRequestProvider(requestDetails);
|
||||
return switch (GeneralSettings.getCurrentState().getSelectedService()) {
|
||||
case CODEGPT -> CompletionClientProvider.getCodeGPTClient()
|
||||
.getCompletionAsync(
|
||||
.getCodeCompletionAsync(
|
||||
CodeCompletionRequestFactory.buildCodeGPTRequest(requestDetails),
|
||||
eventListener);
|
||||
case OPENAI -> CompletionClientProvider.getOpenAIClient()
|
||||
|
|
|
|||
|
|
@ -1,170 +0,0 @@
|
|||
package ee.carlrobert.codegpt.codecompletions
|
||||
|
||||
import com.intellij.codeInsight.inline.completion.InlineCompletionRequest
|
||||
import com.intellij.codeInsight.inline.completion.elements.InlineCompletionGrayTextElement
|
||||
import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionSingleSuggestion
|
||||
import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionVariant
|
||||
import com.intellij.notification.NotificationType
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.runInEdt
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.vcs.VcsException
|
||||
import com.intellij.refactoring.suggested.startOffset
|
||||
import ee.carlrobert.codegpt.EncodingManager
|
||||
import ee.carlrobert.codegpt.codecompletions.psi.CompletionContextService
|
||||
import ee.carlrobert.codegpt.codecompletions.psi.readText
|
||||
import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings
|
||||
import ee.carlrobert.codegpt.ui.OverlayUtil.showNotification
|
||||
import ee.carlrobert.codegpt.util.GitUtil
|
||||
import ee.carlrobert.llm.client.openai.completion.ErrorDetails
|
||||
import ee.carlrobert.llm.completion.CompletionEventListener
|
||||
import git4idea.repo.GitRepositoryManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.sse.EventSource
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
class CodeGPTInlineCompletionSuggestion(
|
||||
private val project: Project,
|
||||
private val inlineCompletionRequest: InlineCompletionRequest
|
||||
) : InlineCompletionSingleSuggestion {
|
||||
|
||||
private val currentCall = AtomicReference<EventSource>(null)
|
||||
|
||||
companion object {
|
||||
private val logger = thisLogger()
|
||||
private const val MAX_PROMPT_TOKENS = 128
|
||||
}
|
||||
|
||||
override suspend fun getVariant() = InlineCompletionVariant.build(elements = channelFlow {
|
||||
val infillRequest = buildInfillRequest(inlineCompletionRequest)
|
||||
launch {
|
||||
val completionCall =
|
||||
project.service<CodeCompletionService>().getCodeCompletionAsync(
|
||||
infillRequest,
|
||||
CodeCompletionEventListener {
|
||||
try {
|
||||
runInEdt {
|
||||
trySend(InlineCompletionGrayTextElement(it.toString()))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger.error("Failed to send inline completion suggestion", e)
|
||||
}
|
||||
}
|
||||
)
|
||||
currentCall.set(completionCall)
|
||||
}
|
||||
awaitClose { currentCall.getAndSet(null)?.cancel() }
|
||||
})
|
||||
|
||||
private class CodeCompletionEventListener(
|
||||
private val completed: (StringBuilder) -> Unit
|
||||
) : CompletionEventListener<String> {
|
||||
|
||||
override fun onComplete(messageBuilder: StringBuilder) {
|
||||
completed(messageBuilder)
|
||||
}
|
||||
|
||||
override fun onCancelled(messageBuilder: StringBuilder) {
|
||||
completed(messageBuilder)
|
||||
}
|
||||
|
||||
override fun onError(error: ErrorDetails, ex: Throwable) {
|
||||
if (ex.message == null || (ex.message != null && ex.message != "Canceled")) {
|
||||
showNotification(error.message, NotificationType.ERROR)
|
||||
logger.error(error.message, ex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun buildInfillRequest(request: InlineCompletionRequest): InfillRequest {
|
||||
val caretOffset = withContext(Dispatchers.EDT) { request.editor.caretModel.offset }
|
||||
val configurationState = service<ConfigurationSettings>().state
|
||||
val (prefix, suffix) = withContext(Dispatchers.EDT) {
|
||||
val prefix =
|
||||
request.document.getText(TextRange(0, caretOffset))
|
||||
val suffix =
|
||||
request.document.getText(
|
||||
TextRange(
|
||||
caretOffset,
|
||||
request.document.textLength
|
||||
)
|
||||
)
|
||||
Pair(
|
||||
prefix.truncateText(MAX_PROMPT_TOKENS, false),
|
||||
suffix.truncateText(MAX_PROMPT_TOKENS)
|
||||
)
|
||||
}
|
||||
val fileExtension = request.file.virtualFile.extension
|
||||
val fileContent = request.document.text
|
||||
val infillRequestBuilder = InfillRequest.Builder(prefix, suffix)
|
||||
.fileDetails(InfillRequest.FileDetails(fileContent, fileExtension))
|
||||
val project = request.editor.project ?: return infillRequestBuilder.build()
|
||||
|
||||
val gitRepository =
|
||||
project.service<GitRepositoryManager>().getRepositoryForFile(project.workspaceFile)
|
||||
if (configurationState.autocompletionGitContextEnabled && gitRepository != null) {
|
||||
try {
|
||||
val stagedDiff = GitUtil.getStagedDiff(project, gitRepository)
|
||||
val unstagedDiff = GitUtil.getUnstagedDiff(project, gitRepository)
|
||||
if (stagedDiff.isNotEmpty() || unstagedDiff.isNotEmpty()) {
|
||||
infillRequestBuilder.vcsDetails(
|
||||
InfillRequest.VcsDetails(
|
||||
stagedDiff.joinToString("\n"),
|
||||
unstagedDiff.joinToString("\n")
|
||||
)
|
||||
)
|
||||
}
|
||||
} catch (e: VcsException) {
|
||||
logger.error("Failed to get git context", e)
|
||||
}
|
||||
}
|
||||
|
||||
getInfillContext(request, caretOffset)?.let { infillRequestBuilder.context(it) }
|
||||
|
||||
return infillRequestBuilder.build()
|
||||
}
|
||||
|
||||
private fun getInfillContext(
|
||||
request: InlineCompletionRequest,
|
||||
caretOffset: Int
|
||||
): InfillContext? {
|
||||
val infillContext =
|
||||
if (service<ConfigurationSettings>().state.autocompletionContextAwareEnabled)
|
||||
service<CompletionContextService>().findContext(request.editor, caretOffset)
|
||||
else null
|
||||
|
||||
if (infillContext == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
val caretInEnclosingElement =
|
||||
caretOffset - infillContext.enclosingElement.psiElement.startOffset
|
||||
val entireText = infillContext.enclosingElement.psiElement.readText()
|
||||
val prefix = entireText.take(caretInEnclosingElement)
|
||||
val suffix =
|
||||
if (entireText.length < caretInEnclosingElement) "" else entireText.takeLast(
|
||||
entireText.length - caretInEnclosingElement
|
||||
)
|
||||
return truncateContext(prefix + suffix, infillContext)
|
||||
}
|
||||
|
||||
private fun String.truncateText(maxTokens: Int, fromStart: Boolean = true): String {
|
||||
return service<EncodingManager>().truncateText(this, maxTokens, fromStart)
|
||||
}
|
||||
|
||||
private fun truncateContext(prompt: String, infillContext: InfillContext): InfillContext {
|
||||
var promptTokens = EncodingManager.getInstance().countTokens(prompt)
|
||||
val truncatedContextElements = infillContext.contextElements.takeWhile {
|
||||
promptTokens += it.tokens
|
||||
promptTokens <= MAX_PROMPT_TOKENS
|
||||
}.toSet()
|
||||
return InfillContext(infillContext.enclosingElement, truncatedContextElements)
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ open class ToolwindowEditorActionLink(
|
|||
private val highlightedText: String,
|
||||
) : AnActionLink(title, action) {
|
||||
|
||||
private val mainEditor = project.service<FileEditorManager>().selectedTextEditor
|
||||
private val mainEditor = FileEditorManager.getInstance(project).selectedTextEditor
|
||||
private val documentListener = object : DocumentListener {
|
||||
override fun documentChanged(event: DocumentEvent) {
|
||||
updateActionState()
|
||||
|
|
|
|||
|
|
@ -15,26 +15,28 @@ import org.assertj.core.api.Assertions.assertThat
|
|||
import testsupport.IntegrationTest
|
||||
|
||||
class CodeCompletionServiceTest : IntegrationTest() {
|
||||
private val cursorPosition = VisualPosition(3, 0)
|
||||
private val cursorPosition = VisualPosition(1, 0)
|
||||
|
||||
fun testFetchCodeCompletionLlama() {
|
||||
useLlamaService()
|
||||
LlamaSettings.getCurrentState().isCodeCompletionsEnabled = true
|
||||
myFixture.configureByText(
|
||||
"CompletionTest.java",
|
||||
getResourceContent("/codecompletions/code-completion-file.txt")
|
||||
"""
|
||||
[INPUT]
|
||||
|
||||
[\INPUT]
|
||||
""".trimIndent()
|
||||
)
|
||||
val editor = myFixture.editor
|
||||
val expectedCompletion = "TEST_SINGLE_LINE_OUTPUT\nTEST_MULTI_LINE_OUTPUT"
|
||||
val prefix = """
|
||||
${"z".repeat(245)}
|
||||
[INPUT]
|
||||
c
|
||||
""".trimIndent() // 128 tokens
|
||||
val suffix = """
|
||||
|
||||
[\INPUT]
|
||||
${"z".repeat(247)}
|
||||
""".trimIndent() // 128 tokens
|
||||
expectLlama(StreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue