mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-22 03:30:04 +00:00
feat: add inception provider
This commit is contained in:
parent
f8b36b294d
commit
da50e55ba1
42 changed files with 674 additions and 183 deletions
|
|
@ -12,7 +12,7 @@ jsoup = "1.21.2"
|
|||
jtokkit = "1.1.0"
|
||||
junit = "5.13.4"
|
||||
kotlin = "2.2.10"
|
||||
llm-client = "0.8.49"
|
||||
llm-client = "0.8.52"
|
||||
okio = "3.15.0"
|
||||
tree-sitter = "0.24.5"
|
||||
grpc = "1.73.0"
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public final class Icons {
|
|||
public static final Icon Meta = IconLoader.getIcon("/icons/meta.svg", Icons.class);
|
||||
public static final Icon Mistral = IconLoader.getIcon("/icons/mistral.svg", Icons.class);
|
||||
public static final Icon Moonshot = IconLoader.getIcon("/icons/moonshot.svg", Icons.class);
|
||||
public static final Icon Inception = IconLoader.getIcon("/icons/inception.svg", Icons.class);
|
||||
public static final Icon Send = IconLoader.getIcon("/icons/send.svg", Icons.class);
|
||||
public static final Icon Sparkle = IconLoader.getIcon("/icons/sparkle.svg", Icons.class);
|
||||
public static final Icon Ollama = IconLoader.getIcon("/icons/ollama.svg", Icons.class);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings;
|
|||
import ee.carlrobert.llm.client.anthropic.ClaudeClient;
|
||||
import ee.carlrobert.llm.client.codegpt.CodeGPTClient;
|
||||
import ee.carlrobert.llm.client.google.GoogleClient;
|
||||
import ee.carlrobert.llm.client.inception.InceptionClient;
|
||||
import ee.carlrobert.llm.client.llama.LlamaClient;
|
||||
import ee.carlrobert.llm.client.mistral.MistralClient;
|
||||
import ee.carlrobert.llm.client.ollama.OllamaClient;
|
||||
|
|
@ -78,6 +79,11 @@ public class CompletionClientProvider {
|
|||
return new MistralClient(getCredential(CredentialKey.MistralApiKey.INSTANCE), getDefaultClientBuilder());
|
||||
}
|
||||
|
||||
public static InceptionClient getInceptionClient() {
|
||||
return new InceptionClient.Builder(getCredential(CredentialKey.InceptionApiKey.INSTANCE))
|
||||
.build(getDefaultClientBuilder());
|
||||
}
|
||||
|
||||
public static OkHttpClient.Builder getDefaultClientBuilder() {
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
CertificateManager certificateManager = CertificateManager.getInstance();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package ee.carlrobert.codegpt.completions;
|
||||
|
||||
import static ee.carlrobert.codegpt.settings.service.ServiceType.INCEPTION;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.Service;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
|
|
@ -14,7 +16,7 @@ import ee.carlrobert.llm.client.anthropic.completion.ClaudeCompletionRequest;
|
|||
import ee.carlrobert.llm.client.codegpt.request.InlineEditRequest;
|
||||
import ee.carlrobert.llm.client.codegpt.request.chat.ChatCompletionRequest;
|
||||
import ee.carlrobert.llm.client.google.completion.GoogleCompletionRequest;
|
||||
import ee.carlrobert.llm.client.llama.completion.LlamaCompletionRequest;
|
||||
import ee.carlrobert.llm.client.inception.request.InceptionApplyRequest;
|
||||
import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionEventSourceListener;
|
||||
import ee.carlrobert.llm.client.openai.completion.OpenAITextCompletionEventSourceListener;
|
||||
import ee.carlrobert.llm.client.openai.completion.request.OpenAIChatCompletionRequest;
|
||||
|
|
@ -75,12 +77,17 @@ public final class CompletionRequestService {
|
|||
public EventSource autoApplyAsync(
|
||||
AutoApplyParameters params,
|
||||
CompletionEventListener<String> eventListener) {
|
||||
var serviceType =
|
||||
var selectedService =
|
||||
ModelSelectionService.getInstance().getServiceForFeature(FeatureType.AUTO_APPLY);
|
||||
|
||||
if (selectedService == INCEPTION) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var request = CompletionRequestFactory
|
||||
.getFactory(serviceType)
|
||||
.getFactory(selectedService)
|
||||
.createAutoApplyRequest(params);
|
||||
return getChatCompletionAsync(request, eventListener, serviceType, FeatureType.AUTO_APPLY);
|
||||
return getChatCompletionAsync(request, eventListener, selectedService, FeatureType.AUTO_APPLY);
|
||||
}
|
||||
|
||||
public EventSource getCommitMessageAsync(
|
||||
|
|
@ -129,6 +136,10 @@ public final class CompletionRequestService {
|
|||
.getChatCompletionAsync(completionRequest, eventListener);
|
||||
case MISTRAL -> CompletionClientProvider.getMistralClient()
|
||||
.getChatCompletionAsync(completionRequest, eventListener);
|
||||
case LLAMA_CPP -> CompletionClientProvider.getLlamaClient()
|
||||
.getChatCompletionAsync(completionRequest, eventListener);
|
||||
case INCEPTION -> CompletionClientProvider.getInceptionClient()
|
||||
.getChatCompletionAsync(completionRequest, eventListener);
|
||||
default -> throw new RuntimeException("Unknown service selected");
|
||||
};
|
||||
}
|
||||
|
|
@ -150,11 +161,6 @@ public final class CompletionRequestService {
|
|||
ModelSelectionService.getInstance().getModelForFeature(featureType, null),
|
||||
eventListener);
|
||||
}
|
||||
if (request instanceof LlamaCompletionRequest completionRequest) {
|
||||
return CompletionClientProvider.getLlamaClient().getChatCompletionAsync(
|
||||
completionRequest,
|
||||
eventListener);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Unknown request type: " + request.getClass());
|
||||
}
|
||||
|
|
@ -169,6 +175,10 @@ public final class CompletionRequestService {
|
|||
.getChatCompletion(completionRequest);
|
||||
case MISTRAL -> CompletionClientProvider.getMistralClient()
|
||||
.getChatCompletion(completionRequest);
|
||||
case LLAMA_CPP -> CompletionClientProvider.getLlamaClient()
|
||||
.getChatCompletion(completionRequest);
|
||||
case INCEPTION -> CompletionClientProvider.getInceptionClient()
|
||||
.getChatCompletion(completionRequest);
|
||||
default -> throw new RuntimeException("Unknown service selected");
|
||||
};
|
||||
return tryExtractContent(response).orElseThrow();
|
||||
|
|
@ -205,11 +215,6 @@ public final class CompletionRequestService {
|
|||
.getContent().getParts().get(0)
|
||||
.getText();
|
||||
}
|
||||
if (request instanceof LlamaCompletionRequest completionRequest) {
|
||||
return CompletionClientProvider.getLlamaClient()
|
||||
.getChatCompletion(completionRequest)
|
||||
.getContent();
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Unknown request type: " + request.getClass());
|
||||
}
|
||||
|
|
@ -235,6 +240,8 @@ public final class CompletionRequestService {
|
|||
case GOOGLE -> CredentialsStore.INSTANCE.isCredentialSet(CredentialKey.GoogleApiKey.INSTANCE);
|
||||
case MISTRAL ->
|
||||
CredentialsStore.INSTANCE.isCredentialSet(CredentialKey.MistralApiKey.INSTANCE);
|
||||
case INCEPTION ->
|
||||
CredentialsStore.INSTANCE.isCredentialSet(CredentialKey.InceptionApiKey.INSTANCE);
|
||||
case PROXYAI, CUSTOM_OPENAI, LLAMA_CPP, OLLAMA -> true;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ public enum ServiceType {
|
|||
GOOGLE("GOOGLE", "service.google.title", "google.chat.completion"),
|
||||
MISTRAL("MISTRAL", "service.mistral.title", "mistral.chat.completion"),
|
||||
LLAMA_CPP("LLAMA_CPP", "service.llama.title", "llama.chat.completion"),
|
||||
OLLAMA("OLLAMA", "service.ollama.title", "ollama.chat.completion");
|
||||
OLLAMA("OLLAMA", "service.ollama.title", "ollama.chat.completion"),
|
||||
INCEPTION("INCEPTION", "service.inception.title", "inception.chat.completion");
|
||||
|
||||
private final String code;
|
||||
private final String label;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import static ee.carlrobert.codegpt.settings.service.ServiceType.MISTRAL;
|
|||
import static ee.carlrobert.codegpt.settings.service.ServiceType.OLLAMA;
|
||||
import static ee.carlrobert.codegpt.settings.service.ServiceType.OPENAI;
|
||||
import static ee.carlrobert.codegpt.settings.service.ServiceType.PROXYAI;
|
||||
import static ee.carlrobert.codegpt.settings.service.ServiceType.INCEPTION;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.ActionUpdateThread;
|
||||
|
|
@ -242,6 +243,13 @@ public class ModelComboBoxAction extends ComboBoxAction {
|
|||
actionGroup.add(mistralGroup);
|
||||
}
|
||||
|
||||
if (availableProviders.contains(INCEPTION)) {
|
||||
var inceptionGroup = DefaultActionGroup.createPopupGroup(() -> "Inception");
|
||||
inceptionGroup.getTemplatePresentation().setIcon(Icons.Inception);
|
||||
inceptionGroup.add(createInceptionModelAction(presentation));
|
||||
actionGroup.add(inceptionGroup);
|
||||
}
|
||||
|
||||
if (availableProviders.contains(LLAMA_CPP) || availableProviders.contains(OLLAMA)) {
|
||||
actionGroup.addSeparator("Offline");
|
||||
|
||||
|
|
@ -344,6 +352,11 @@ public class ModelComboBoxAction extends ComboBoxAction {
|
|||
templatePresentation.setText(getMistralPresentationText());
|
||||
templatePresentation.setIcon(Icons.Mistral);
|
||||
break;
|
||||
case INCEPTION:
|
||||
templatePresentation.setIcon(Icons.Inception);
|
||||
var inceptionModelName = ModelRegistry.getInstance().getModelDisplayName(INCEPTION, modelCode);
|
||||
templatePresentation.setText(inceptionModelName);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -525,6 +538,18 @@ public class ModelComboBoxAction extends ComboBoxAction {
|
|||
.setModel(featureType, modelCode, MISTRAL));
|
||||
}
|
||||
|
||||
private AnAction createInceptionModelAction(Presentation comboBoxPresentation) {
|
||||
var modelCode = ModelRegistry.MERCURY_CODER;
|
||||
var modelName = ModelRegistry.getInstance().getModelDisplayName(INCEPTION, modelCode);
|
||||
return createModelAction(
|
||||
INCEPTION,
|
||||
modelName,
|
||||
Icons.Inception,
|
||||
comboBoxPresentation,
|
||||
() -> ApplicationManager.getApplication().getService(ModelSettings.class)
|
||||
.setModel(featureType, modelCode, INCEPTION));
|
||||
}
|
||||
|
||||
private String getMistralPresentationText() {
|
||||
var chatModel = ApplicationManager.getApplication().getService(ModelSettings.class).getState()
|
||||
.getModelSelection(featureType);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings
|
|||
import ee.carlrobert.codegpt.settings.service.ollama.OllamaSettings
|
||||
import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings
|
||||
import ee.carlrobert.codegpt.settings.service.mistral.MistralSettings
|
||||
import ee.carlrobert.codegpt.settings.service.inception.InceptionSettings
|
||||
|
||||
abstract class CodeCompletionFeatureToggleActions(
|
||||
private val enableFeatureAction: Boolean
|
||||
|
|
@ -50,6 +51,10 @@ abstract class CodeCompletionFeatureToggleActions(
|
|||
MistralSettings.getCurrentState().isCodeCompletionsEnabled = enableFeatureAction
|
||||
}
|
||||
|
||||
INCEPTION -> {
|
||||
service<InceptionSettings>().state.codeCompletionsEnabled = enableFeatureAction
|
||||
}
|
||||
|
||||
ANTHROPIC,
|
||||
GOOGLE -> {
|
||||
}
|
||||
|
|
@ -68,7 +73,8 @@ abstract class CodeCompletionFeatureToggleActions(
|
|||
CUSTOM_OPENAI,
|
||||
LLAMA_CPP,
|
||||
OLLAMA,
|
||||
MISTRAL -> true
|
||||
MISTRAL,
|
||||
INCEPTION -> true
|
||||
|
||||
ANTHROPIC,
|
||||
GOOGLE -> false
|
||||
|
|
|
|||
|
|
@ -10,11 +10,15 @@ import com.intellij.openapi.diagnostic.thisLogger
|
|||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys
|
||||
import ee.carlrobert.codegpt.codecompletions.edit.NextEditCoordinator
|
||||
import ee.carlrobert.codegpt.codecompletions.edit.GrpcClientService
|
||||
import ee.carlrobert.codegpt.predictions.CodeSuggestionDiffViewer
|
||||
import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings
|
||||
import ee.carlrobert.codegpt.settings.service.FeatureType
|
||||
import ee.carlrobert.codegpt.settings.service.ModelSelectionService
|
||||
import ee.carlrobert.codegpt.settings.service.ServiceType
|
||||
import ee.carlrobert.codegpt.settings.service.ServiceType.INCEPTION
|
||||
import ee.carlrobert.codegpt.settings.service.ServiceType.PROXYAI
|
||||
import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTServiceSettings
|
||||
import ee.carlrobert.codegpt.treesitter.CodeCompletionParserFactory
|
||||
import ee.carlrobert.codegpt.ui.OverlayUtil.showNotification
|
||||
|
|
@ -27,7 +31,7 @@ import java.util.concurrent.atomic.AtomicBoolean
|
|||
|
||||
class CodeCompletionEventListener(
|
||||
private val editor: Editor,
|
||||
private val channel: ProducerScope<InlineCompletionElement>
|
||||
private val channel: ProducerScope<InlineCompletionElement>,
|
||||
) : CompletionEventListener<String> {
|
||||
|
||||
companion object {
|
||||
|
|
@ -178,10 +182,12 @@ class CodeCompletionEventListener(
|
|||
setLoading(false)
|
||||
|
||||
if (messageBuilder.isEmpty()) {
|
||||
editor.project?.service<GrpcClientService>()?.getNextEdit(
|
||||
NextEditCoordinator.requestNextEdit(
|
||||
editor,
|
||||
prefix + suffix,
|
||||
runReadAction { editor.caretModel.offset })
|
||||
runReadAction { editor.caretModel.offset },
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import com.intellij.openapi.application.runInEdt
|
|||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.components.service
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys
|
||||
import ee.carlrobert.codegpt.codecompletions.edit.GrpcClientService
|
||||
import ee.carlrobert.codegpt.codecompletions.edit.NextEditCoordinator
|
||||
import ee.carlrobert.codegpt.predictions.CodeSuggestionDiffViewer
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -32,23 +32,23 @@ class CodeCompletionInsertHandler : InlineCompletionInsertHandler {
|
|||
val prefix = editor.document.text.substring(0, caretOffset)
|
||||
val suffix = editor.document.text.substring(caretOffset)
|
||||
CoroutineScope(SupervisorJob() + Dispatchers.IO).launch {
|
||||
editor.project?.service<GrpcClientService>()
|
||||
?.getNextEdit(
|
||||
editor,
|
||||
prefix + remainingCompletion.partialCompletion + suffix,
|
||||
caretOffset + remainingCompletion.partialCompletion.length,
|
||||
true
|
||||
)
|
||||
NextEditCoordinator.requestNextEdit(
|
||||
editor,
|
||||
prefix + remainingCompletion.partialCompletion + suffix,
|
||||
caretOffset + remainingCompletion.partialCompletion.length,
|
||||
true
|
||||
)
|
||||
}
|
||||
return
|
||||
} else {
|
||||
if (CodeGPTKeys.REMAINING_PREDICTION_RESPONSE.get(editor) == null) {
|
||||
val caretOffset = runReadAction { editor.caretModel.offset }
|
||||
CoroutineScope(SupervisorJob() + Dispatchers.IO).launch {
|
||||
editor.project?.service<GrpcClientService>()?.getNextEdit(
|
||||
NextEditCoordinator.requestNextEdit(
|
||||
editor,
|
||||
editor.document.text,
|
||||
caretOffset,
|
||||
false
|
||||
)
|
||||
}
|
||||
return
|
||||
|
|
@ -64,4 +64,4 @@ class CodeCompletionInsertHandler : InlineCompletionInsertHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import ee.carlrobert.codegpt.settings.service.custom.CustomServicesSettings
|
|||
import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings
|
||||
import ee.carlrobert.codegpt.settings.service.llama.LlamaSettingsState
|
||||
import ee.carlrobert.codegpt.settings.service.ollama.OllamaSettings
|
||||
import ee.carlrobert.llm.client.inception.request.InceptionFIMRequest
|
||||
import ee.carlrobert.llm.client.llama.completion.LlamaCompletionRequest
|
||||
import ee.carlrobert.llm.client.ollama.completion.request.OllamaCompletionRequest
|
||||
import ee.carlrobert.llm.client.ollama.completion.request.OllamaParameters
|
||||
|
|
@ -237,6 +238,16 @@ object CodeCompletionRequestFactory {
|
|||
.build()
|
||||
}
|
||||
|
||||
fun buildInceptionRequest(details: InfillRequest): InceptionFIMRequest {
|
||||
val model = service<ModelSelectionService>().getModelForFeature(FeatureType.CODE_COMPLETION)
|
||||
return InceptionFIMRequest.Builder()
|
||||
.setPrompt(details.prefix)
|
||||
.setSuffix(details.suffix)
|
||||
.setModel(model)
|
||||
.setStream(true)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun getLlamaInfillPromptTemplate(settings: LlamaSettingsState): InfillPromptTemplate {
|
||||
if (settings.isUseCustomModel) {
|
||||
return settings.localModelInfillPromptTemplate
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.intellij.openapi.components.service
|
|||
import com.intellij.openapi.project.Project
|
||||
import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory.buildChatBasedFIMHttpRequest
|
||||
import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory.buildCustomRequest
|
||||
import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory.buildInceptionRequest
|
||||
import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory.buildLlamaRequest
|
||||
import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory.buildOllamaRequest
|
||||
import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory.buildOpenAIRequest
|
||||
|
|
@ -17,6 +18,7 @@ import ee.carlrobert.codegpt.settings.service.ServiceType
|
|||
import ee.carlrobert.codegpt.settings.service.ServiceType.*
|
||||
import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTServiceSettings
|
||||
import ee.carlrobert.codegpt.settings.service.custom.CustomServicesSettings
|
||||
import ee.carlrobert.codegpt.settings.service.inception.InceptionSettings
|
||||
import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings
|
||||
import ee.carlrobert.codegpt.settings.service.mistral.MistralSettings
|
||||
import ee.carlrobert.codegpt.settings.service.ollama.OllamaSettings
|
||||
|
|
@ -46,9 +48,11 @@ class CodeCompletionService(private val project: Project) {
|
|||
.customServiceStateForFeatureType(FeatureType.CODE_COMPLETION)
|
||||
.codeCompletionSettings
|
||||
.codeCompletionsEnabled
|
||||
|
||||
MISTRAL -> MistralSettings.getCurrentState().isCodeCompletionsEnabled
|
||||
LLAMA_CPP -> LlamaSettings.isCodeCompletionsPossible()
|
||||
OLLAMA -> service<OllamaSettings>().state.codeCompletionsEnabled
|
||||
INCEPTION -> service<InceptionSettings>().state.codeCompletionsEnabled
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +77,11 @@ class CodeCompletionService(private val project: Project) {
|
|||
val isChatBasedFIM =
|
||||
customSettings.infillTemplate == InfillPromptTemplate.CHAT_COMPLETION
|
||||
if (isChatBasedFIM) {
|
||||
val credential = getCredential(CredentialKey.CustomServiceApiKeyById(requireNotNull(activeService.id)))
|
||||
val credential = getCredential(
|
||||
CredentialKey.CustomServiceApiKeyById(
|
||||
requireNotNull(activeService.id)
|
||||
)
|
||||
)
|
||||
createFactory(
|
||||
CompletionClientProvider.getDefaultClientBuilder().build()
|
||||
).newEventSource(
|
||||
|
|
@ -107,7 +115,10 @@ class CodeCompletionService(private val project: Project) {
|
|||
.getCompletionAsync(buildOllamaRequest(infillRequest), eventListener)
|
||||
|
||||
LLAMA_CPP -> CompletionClientProvider.getLlamaClient()
|
||||
.getChatCompletionAsync(buildLlamaRequest(infillRequest), eventListener)
|
||||
.getCodeCompletionAsync(buildLlamaRequest(infillRequest), eventListener)
|
||||
|
||||
INCEPTION -> CompletionClientProvider.getInceptionClient()
|
||||
.getFimCompletionAsync(buildInceptionRequest(infillRequest), eventListener)
|
||||
|
||||
else -> throw IllegalArgumentException("Code completion not supported for ${selectedService.name}")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import ee.carlrobert.codegpt.settings.service.ModelSelectionService
|
|||
import ee.carlrobert.codegpt.settings.service.ServiceType
|
||||
import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTServiceSettings
|
||||
import ee.carlrobert.codegpt.settings.service.custom.CustomServicesSettings
|
||||
import ee.carlrobert.codegpt.settings.service.inception.InceptionSettings
|
||||
import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings
|
||||
import ee.carlrobert.codegpt.settings.service.mistral.MistralSettings
|
||||
import ee.carlrobert.codegpt.settings.service.ollama.OllamaSettings
|
||||
|
|
@ -117,6 +118,7 @@ class DebouncedCodeCompletionProvider : DebouncedInlineCompletionProvider() {
|
|||
ServiceType.LLAMA_CPP -> LlamaSettings.isCodeCompletionsPossible()
|
||||
ServiceType.OLLAMA -> service<OllamaSettings>().state.codeCompletionsEnabled
|
||||
ServiceType.MISTRAL -> MistralSettings.getCurrentState().isCodeCompletionsEnabled
|
||||
ServiceType.INCEPTION -> service<InceptionSettings>().state.codeCompletionsEnabled
|
||||
ServiceType.ANTHROPIC,
|
||||
ServiceType.GOOGLE,
|
||||
null -> false
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.intellij.codeInsight.inline.completion.elements.InlineCompletionEleme
|
|||
import com.intellij.notification.NotificationType
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import ee.carlrobert.codegpt.codecompletions.CodeCompletionEventListener
|
||||
import ee.carlrobert.llm.client.openai.completion.ErrorDetails
|
||||
import ee.carlrobert.codegpt.ui.OverlayUtil
|
||||
import ee.carlrobert.service.PartialCodeCompletionResponse
|
||||
import io.grpc.Status
|
||||
|
|
@ -45,10 +46,11 @@ class CodeCompletionStreamObserver(
|
|||
NotificationType.ERROR
|
||||
)
|
||||
}
|
||||
eventListener.onError(ErrorDetails(t?.message ?: "Code completion error"), t ?: Throwable())
|
||||
channel.close(t)
|
||||
}
|
||||
|
||||
override fun onCompleted() {
|
||||
eventListener.onComplete(messageBuilder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ import java.util.concurrent.TimeUnit
|
|||
class GrpcClientService(private val project: Project) : Disposable {
|
||||
|
||||
private var channel: ManagedChannel? = null
|
||||
private var codeCompletionStub: CodeCompletionServiceImplGrpc.CodeCompletionServiceImplStub? =
|
||||
null
|
||||
private var codeCompletionStub: CodeCompletionServiceImplGrpc.CodeCompletionServiceImplStub? = null
|
||||
private var codeCompletionObserver: CodeCompletionStreamObserver? = null
|
||||
private var nextEditStub: NextEditServiceImplGrpc.NextEditServiceImplStub? = null
|
||||
private var nextEditStreamObserver: NextEditStreamObserver? = null
|
||||
|
|
@ -63,7 +62,7 @@ class GrpcClientService(private val project: Project) : Disposable {
|
|||
caretOffset: Int,
|
||||
addToQueue: Boolean = false,
|
||||
) {
|
||||
if (service<ModelSelectionService>().getServiceForFeature(FeatureType.CODE_COMPLETION) != ServiceType.PROXYAI
|
||||
if (service<ModelSelectionService>().getServiceForFeature(FeatureType.NEXT_EDIT) != ServiceType.PROXYAI
|
||||
|| !service<CodeGPTServiceSettings>().state.nextEditsEnabled
|
||||
) {
|
||||
return
|
||||
|
|
@ -199,4 +198,4 @@ class GrpcClientService(private val project: Project) : Disposable {
|
|||
}
|
||||
channel = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,130 @@
|
|||
package ee.carlrobert.codegpt.codecompletions.edit
|
||||
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import ee.carlrobert.codegpt.EncodingManager
|
||||
import ee.carlrobert.codegpt.completions.CompletionClientProvider
|
||||
import ee.carlrobert.codegpt.settings.models.ModelRegistry
|
||||
import ee.carlrobert.codegpt.settings.service.FeatureType
|
||||
import ee.carlrobert.codegpt.settings.service.ModelSelectionService
|
||||
import ee.carlrobert.codegpt.settings.service.ServiceType
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.parser.SseMessageParser
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.parser.SearchReplace
|
||||
import ee.carlrobert.codegpt.util.GitUtil
|
||||
import ee.carlrobert.service.NextEditResponse
|
||||
import ee.carlrobert.llm.client.inception.request.InceptionNextEditRequest
|
||||
import ee.carlrobert.llm.client.openai.completion.request.OpenAIChatCompletionStandardMessage
|
||||
import java.util.*
|
||||
|
||||
object InceptionNextEditRunner {
|
||||
|
||||
private val logger = thisLogger()
|
||||
|
||||
fun isEnabled(): Boolean {
|
||||
return service<ModelSelectionService>().getServiceForFeature(FeatureType.NEXT_EDIT) == ServiceType.INCEPTION
|
||||
}
|
||||
|
||||
fun run(editor: Editor, fileContent: String, caretOffset: Int, addToQueue: Boolean = false, onResult: (NextEditResponse) -> Unit) {
|
||||
try {
|
||||
val safeOffset = caretOffset.coerceIn(0, fileContent.length)
|
||||
val codeWithCursor = buildString {
|
||||
append(fileContent.substring(0, safeOffset))
|
||||
append("<|cursor|>")
|
||||
append(fileContent.substring(safeOffset))
|
||||
}
|
||||
|
||||
val content = buildString {
|
||||
append("<|recently_viewed_code_snippets|>\n")
|
||||
append("<|/recently_viewed_code_snippets|>\n")
|
||||
append("<|current_file_content|>\n")
|
||||
append(fileContent)
|
||||
append("\n<|code_to_edit|>\n")
|
||||
append(codeWithCursor)
|
||||
append("\n<|/code_to_edit|>")
|
||||
append("<|/current_file_content|>\n")
|
||||
append("<|edit_diff_history|>\n")
|
||||
append(buildEditDiffHistory(editor.project))
|
||||
append("\n<|/edit_diff_history|>")
|
||||
}
|
||||
|
||||
val message = OpenAIChatCompletionStandardMessage("user", content)
|
||||
val request = InceptionNextEditRequest.Builder()
|
||||
.setModel(ModelRegistry.MERCURY_CODER)
|
||||
.setMessages(listOf(message))
|
||||
.build()
|
||||
|
||||
val response = CompletionClientProvider.getInceptionClient().getNextEditCompletion(request)
|
||||
val text = response.choices?.firstOrNull()?.message?.content ?: return
|
||||
|
||||
val next = extractNextRevision(text, fileContent)
|
||||
val result = NextEditResponse.newBuilder()
|
||||
.setId(UUID.randomUUID().toString())
|
||||
.setOldRevision(fileContent)
|
||||
.setNextRevision(next)
|
||||
.build()
|
||||
onResult(result)
|
||||
} catch (ex: Exception) {
|
||||
logger.error("Something went wrong while retrieving next edit completion", ex)
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractNextRevision(message: String, source: String): String {
|
||||
// If model returned a fenced full file, extract it directly
|
||||
extractTripleBacktickCode(message)?.let { fenced ->
|
||||
if (fenced.isNotBlank()) return fenced
|
||||
}
|
||||
|
||||
val parser = SseMessageParser()
|
||||
val segments = parser.parse(message)
|
||||
var result = source
|
||||
segments.forEach { seg ->
|
||||
if (seg is SearchReplace) {
|
||||
val search = seg.search.trim()
|
||||
val replace = seg.replace
|
||||
if (search.isNotEmpty() && result.contains(search)) {
|
||||
result = result.replaceFirst(search, replace)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun extractTripleBacktickCode(message: String): String? {
|
||||
val fence = "```"
|
||||
val start = message.indexOf(fence)
|
||||
if (start == -1) return null
|
||||
// Skip optional language id on the opening fence
|
||||
var contentStart = start + fence.length
|
||||
if (contentStart < message.length && message[contentStart] == '\n') {
|
||||
contentStart += 1
|
||||
} else {
|
||||
val nl = message.indexOf('\n', contentStart)
|
||||
if (nl != -1) contentStart = nl + 1
|
||||
}
|
||||
val end = message.indexOf(fence, contentStart)
|
||||
if (end == -1) return null
|
||||
return message.substring(contentStart, end).trim()
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildEditDiffHistory(project: Project?): String {
|
||||
if (project == null) return ""
|
||||
|
||||
val sb = StringBuilder()
|
||||
|
||||
// Unstaged/staged current changes first
|
||||
try {
|
||||
GitUtil.getCurrentChanges(project)?.let { diff ->
|
||||
if (diff.isNotBlank()) {
|
||||
sb.append(diff.trim()).append('\n')
|
||||
}
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
val combined = sb.toString().trim()
|
||||
return service<EncodingManager>().truncateText(combined, 2048, true)
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package ee.carlrobert.codegpt.codecompletions.edit
|
||||
|
||||
import com.intellij.openapi.application.runInEdt
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys
|
||||
import ee.carlrobert.codegpt.predictions.CodeSuggestionDiffViewer
|
||||
import ee.carlrobert.codegpt.settings.service.FeatureType
|
||||
import ee.carlrobert.codegpt.settings.service.ModelSelectionService
|
||||
import ee.carlrobert.codegpt.settings.service.ServiceType.INCEPTION
|
||||
import ee.carlrobert.codegpt.settings.service.ServiceType.PROXYAI
|
||||
import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTServiceSettings
|
||||
import ee.carlrobert.codegpt.settings.service.inception.InceptionSettings
|
||||
|
||||
object NextEditCoordinator {
|
||||
|
||||
fun requestNextEdit(
|
||||
editor: Editor,
|
||||
fileContent: String,
|
||||
caretOffset: Int = runReadAction { editor.caretModel.offset },
|
||||
addToQueue: Boolean = false,
|
||||
) {
|
||||
val provider = service<ModelSelectionService>().getServiceForFeature(FeatureType.NEXT_EDIT)
|
||||
when (provider) {
|
||||
PROXYAI -> {
|
||||
if (!service<CodeGPTServiceSettings>().state.nextEditsEnabled) {
|
||||
return
|
||||
}
|
||||
|
||||
editor.project?.service<GrpcClientService>()?.getNextEdit(
|
||||
editor,
|
||||
fileContent,
|
||||
caretOffset,
|
||||
addToQueue
|
||||
)
|
||||
}
|
||||
|
||||
INCEPTION -> {
|
||||
if (!service<InceptionSettings>().state.nextEditsEnabled) {
|
||||
return
|
||||
}
|
||||
|
||||
InceptionNextEditRunner.run(
|
||||
editor,
|
||||
fileContent,
|
||||
caretOffset,
|
||||
addToQueue
|
||||
) { response ->
|
||||
if (addToQueue) {
|
||||
CodeGPTKeys.REMAINING_PREDICTION_RESPONSE.set(editor, response)
|
||||
} else {
|
||||
runInEdt {
|
||||
if (editor.document.text == response.oldRevision) {
|
||||
CodeSuggestionDiffViewer.displayInlineDiff(editor, response)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ interface CompletionRequestFactory {
|
|||
ServiceType.MISTRAL -> MistralRequestFactory()
|
||||
ServiceType.OLLAMA -> OllamaRequestFactory()
|
||||
ServiceType.LLAMA_CPP -> LlamaRequestFactory()
|
||||
ServiceType.INCEPTION -> InceptionRequestFactory()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
package ee.carlrobert.codegpt.completions.factory
|
||||
|
||||
import com.intellij.openapi.components.service
|
||||
import ee.carlrobert.codegpt.completions.*
|
||||
import ee.carlrobert.codegpt.settings.prompts.CoreActionsState
|
||||
import ee.carlrobert.codegpt.settings.prompts.PromptsSettings
|
||||
import ee.carlrobert.codegpt.settings.service.FeatureType
|
||||
import ee.carlrobert.codegpt.settings.service.ModelSelectionService
|
||||
import ee.carlrobert.codegpt.util.EditorUtil
|
||||
import ee.carlrobert.llm.client.inception.request.InceptionApplyRequest
|
||||
import ee.carlrobert.llm.client.openai.completion.request.OpenAIChatCompletionRequest
|
||||
import ee.carlrobert.llm.client.openai.completion.request.OpenAIChatCompletionStandardMessage
|
||||
import ee.carlrobert.llm.completion.CompletionRequest
|
||||
|
||||
class InceptionRequestFactory : BaseRequestFactory() {
|
||||
|
||||
override fun createChatRequest(params: ChatCompletionParameters): OpenAIChatCompletionRequest {
|
||||
val model = ModelSelectionService.getInstance().getModelForFeature(FeatureType.CHAT)
|
||||
val messages = OpenAIRequestFactory.buildOpenAIMessages(
|
||||
model = model,
|
||||
callParameters = params
|
||||
)
|
||||
return OpenAIChatCompletionRequest.Builder(messages)
|
||||
.setModel(model)
|
||||
.setStream(true)
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun createInlineEditRequest(params: InlineEditCompletionParameters): OpenAIChatCompletionRequest {
|
||||
val model = ModelSelectionService.getInstance().getModelForFeature(FeatureType.INLINE_EDIT)
|
||||
val prepared = prepareInlineEditPrompts(params)
|
||||
val messages = OpenAIRequestFactory.buildInlineEditMessages(prepared, params.conversation)
|
||||
return OpenAIChatCompletionRequest.Builder(messages)
|
||||
.setModel(model)
|
||||
.setStream(true)
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun createAutoApplyRequest(params: AutoApplyParameters): CompletionRequest {
|
||||
val model = ModelSelectionService.getInstance().getModelForFeature(FeatureType.AUTO_APPLY)
|
||||
val prompt =
|
||||
"<|original_code|>\n" + EditorUtil.getFileContent(params.destination) + "\n<|/original_code|>\n\n<|update_snippet|>\n// ... existing code ...\n" + params.source + "\n// ... existing code ...\n<|/update_snippet|>"
|
||||
|
||||
return InceptionApplyRequest.Builder()
|
||||
.setModel(model)
|
||||
.setMessages(
|
||||
listOf(
|
||||
OpenAIChatCompletionStandardMessage("user", prompt)
|
||||
)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun createBasicCompletionRequest(
|
||||
systemPrompt: String,
|
||||
userPrompt: String,
|
||||
maxTokens: Int,
|
||||
stream: Boolean,
|
||||
featureType: FeatureType
|
||||
): CompletionRequest {
|
||||
val model = ModelSelectionService.getInstance().getModelForFeature(featureType)
|
||||
return OpenAIChatCompletionRequest.Builder(
|
||||
listOf(
|
||||
OpenAIChatCompletionStandardMessage("system", systemPrompt),
|
||||
OpenAIChatCompletionStandardMessage("user", userPrompt)
|
||||
)
|
||||
)
|
||||
.setModel(model)
|
||||
.setStream(stream)
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun createCommitMessageRequest(params: CommitMessageCompletionParameters): OpenAIChatCompletionRequest {
|
||||
val model =
|
||||
ModelSelectionService.getInstance().getModelForFeature(FeatureType.COMMIT_MESSAGE)
|
||||
val (gitDiff, systemPrompt) = params
|
||||
return OpenAIChatCompletionRequest.Builder(
|
||||
listOf(
|
||||
OpenAIChatCompletionStandardMessage("system", systemPrompt),
|
||||
OpenAIChatCompletionStandardMessage("user", gitDiff)
|
||||
)
|
||||
)
|
||||
.setModel(model)
|
||||
.setStream(true)
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun createLookupRequest(params: LookupCompletionParameters): OpenAIChatCompletionRequest {
|
||||
val model = ModelSelectionService.getInstance().getModelForFeature(FeatureType.LOOKUP)
|
||||
val (prompt) = params
|
||||
val systemPrompt =
|
||||
service<PromptsSettings>().state.coreActions.generateNameLookups.instructions
|
||||
?: CoreActionsState.DEFAULT_GENERATE_NAME_LOOKUPS_PROMPT
|
||||
|
||||
return OpenAIChatCompletionRequest.Builder(
|
||||
listOf(
|
||||
OpenAIChatCompletionStandardMessage("system", systemPrompt),
|
||||
OpenAIChatCompletionStandardMessage("user", prompt)
|
||||
)
|
||||
)
|
||||
.setModel(model)
|
||||
.setStream(false)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2,42 +2,28 @@ package ee.carlrobert.codegpt.completions.factory
|
|||
|
||||
import com.intellij.openapi.components.service
|
||||
import ee.carlrobert.codegpt.completions.BaseRequestFactory
|
||||
import ee.carlrobert.codegpt.completions.InlineEditCompletionParameters
|
||||
import ee.carlrobert.codegpt.completions.ChatCompletionParameters
|
||||
import ee.carlrobert.codegpt.completions.ConversationType
|
||||
import ee.carlrobert.codegpt.completions.llama.LlamaModel
|
||||
import ee.carlrobert.codegpt.completions.llama.PromptTemplate
|
||||
import ee.carlrobert.codegpt.completions.InlineEditCompletionParameters
|
||||
import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings
|
||||
import ee.carlrobert.codegpt.settings.prompts.FilteredPromptsService
|
||||
import ee.carlrobert.codegpt.settings.prompts.PromptsSettings
|
||||
import ee.carlrobert.codegpt.settings.prompts.addProjectPath
|
||||
import ee.carlrobert.codegpt.settings.service.FeatureType
|
||||
import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings
|
||||
import ee.carlrobert.llm.client.llama.completion.LlamaCompletionRequest
|
||||
import ee.carlrobert.codegpt.settings.service.ModelSelectionService
|
||||
import ee.carlrobert.llm.client.openai.completion.request.OpenAIChatCompletionRequest
|
||||
import ee.carlrobert.llm.client.openai.completion.request.OpenAIChatCompletionStandardMessage
|
||||
|
||||
class LlamaRequestFactory : BaseRequestFactory() {
|
||||
|
||||
override fun createChatRequest(params: ChatCompletionParameters): LlamaCompletionRequest {
|
||||
val promptTemplate = getPromptTemplate()
|
||||
var systemPrompt =
|
||||
if (params.conversationType == ConversationType.FIX_COMPILE_ERRORS) {
|
||||
service<PromptsSettings>().state.coreActions.fixCompileErrors.instructions
|
||||
} else {
|
||||
service<PromptsSettings>().state.personas.selectedPersona.let {
|
||||
if (it.disabled) null else service<FilteredPromptsService>().getFilteredPersonaPrompt(
|
||||
params.chatMode
|
||||
).addProjectPath()
|
||||
}
|
||||
}
|
||||
systemPrompt = systemPrompt?.let { service<FilteredPromptsService>().applyClickableLinks(it) }
|
||||
|
||||
val prompt = promptTemplate.buildPrompt(
|
||||
systemPrompt,
|
||||
getPromptWithFilesContext(params),
|
||||
params.conversation.messages
|
||||
override fun createChatRequest(params: ChatCompletionParameters): OpenAIChatCompletionRequest {
|
||||
val model = ModelSelectionService.getInstance().getModelForFeature(FeatureType.CHAT)
|
||||
val configuration = service<ConfigurationSettings>().state
|
||||
return OpenAIChatCompletionRequest.Builder(
|
||||
OpenAIRequestFactory.buildOpenAIMessages(model, params)
|
||||
)
|
||||
|
||||
return buildLlamaRequest(prompt, promptTemplate.stopTokens, true)
|
||||
.setModel(model)
|
||||
.setStream(true)
|
||||
.setMaxTokens(null)
|
||||
.setMaxCompletionTokens(configuration.maxTokens)
|
||||
.setTemperature(configuration.temperature.toDouble())
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun createBasicCompletionRequest(
|
||||
|
|
@ -46,46 +32,32 @@ class LlamaRequestFactory : BaseRequestFactory() {
|
|||
maxTokens: Int,
|
||||
stream: Boolean,
|
||||
featureType: FeatureType
|
||||
): LlamaCompletionRequest {
|
||||
val promptTemplate = getPromptTemplate(featureType)
|
||||
val finalPrompt =
|
||||
promptTemplate.buildPrompt(systemPrompt, userPrompt, listOf())
|
||||
|
||||
return buildLlamaRequest(finalPrompt, emptyList(), stream)
|
||||
}
|
||||
|
||||
override fun createInlineEditRequest(params: InlineEditCompletionParameters): LlamaCompletionRequest {
|
||||
val prepared = prepareInlineEditPrompts(params)
|
||||
val promptTemplate = getPromptTemplate(FeatureType.INLINE_EDIT)
|
||||
val history = params.conversation?.messages?.filter { !it.response.isNullOrBlank() } ?: listOf()
|
||||
val finalPrompt = promptTemplate.buildPrompt(prepared.systemPrompt, prepared.userPrompt, history)
|
||||
return buildLlamaRequest(finalPrompt, emptyList(), stream = true)
|
||||
}
|
||||
|
||||
private fun getPromptTemplate(featureType: FeatureType? = null): PromptTemplate {
|
||||
val settings = service<LlamaSettings>().state
|
||||
return if (settings.isUseCustomModel)
|
||||
settings.localModelPromptTemplate
|
||||
else
|
||||
LlamaModel.findByHuggingFaceModel(settings.huggingFaceModel).promptTemplate
|
||||
}
|
||||
|
||||
private fun buildLlamaRequest(
|
||||
prompt: String,
|
||||
stopTokens: List<String>,
|
||||
stream: Boolean = false
|
||||
): LlamaCompletionRequest {
|
||||
val configSettings = service<ConfigurationSettings>().state
|
||||
val llamaSettings = service<LlamaSettings>().state
|
||||
return LlamaCompletionRequest.Builder(prompt)
|
||||
.setN_predict(configSettings.maxTokens)
|
||||
.setTemperature(configSettings.temperature.toDouble())
|
||||
.setTop_k(llamaSettings.topK)
|
||||
.setTop_p(llamaSettings.topP)
|
||||
.setMin_p(llamaSettings.minP)
|
||||
.setRepeat_penalty(llamaSettings.repeatPenalty)
|
||||
.setStop(stopTokens)
|
||||
): OpenAIChatCompletionRequest {
|
||||
val model = ModelSelectionService.getInstance().getModelForFeature(featureType)
|
||||
val configuration = service<ConfigurationSettings>().state
|
||||
return OpenAIChatCompletionRequest.Builder(
|
||||
listOf(
|
||||
OpenAIChatCompletionStandardMessage("system", systemPrompt),
|
||||
OpenAIChatCompletionStandardMessage("user", userPrompt)
|
||||
)
|
||||
)
|
||||
.setModel(model)
|
||||
.setStream(stream)
|
||||
.setMaxTokens(null)
|
||||
.setMaxCompletionTokens(maxTokens)
|
||||
.setTemperature(configuration.temperature.toDouble())
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun createInlineEditRequest(params: InlineEditCompletionParameters): OpenAIChatCompletionRequest {
|
||||
val model = ModelSelectionService.getInstance().getModelForFeature(FeatureType.INLINE_EDIT)
|
||||
val prepared = prepareInlineEditPrompts(params)
|
||||
val messages = OpenAIRequestFactory.buildInlineEditMessages(prepared, params.conversation)
|
||||
val configuration = service<ConfigurationSettings>().state
|
||||
return OpenAIChatCompletionRequest.Builder(messages)
|
||||
.setModel(model)
|
||||
.setStream(true)
|
||||
.setTemperature(configuration.temperature.toDouble())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,5 +77,9 @@ object CredentialsStore {
|
|||
data object MistralApiKey : CredentialKey() {
|
||||
override val value: String = "MISTRAL_API_KEY"
|
||||
}
|
||||
|
||||
data object InceptionApiKey : CredentialKey() {
|
||||
override val value: String = "INCEPTION_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ import com.intellij.util.ui.JBUI
|
|||
import com.intellij.util.ui.components.BorderLayoutPanel
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys
|
||||
import ee.carlrobert.codegpt.codecompletions.edit.GrpcClientService
|
||||
import ee.carlrobert.codegpt.codecompletions.edit.NextEditCoordinator
|
||||
import ee.carlrobert.codegpt.telemetry.ui.preferences.TelemetryConfigurable
|
||||
import ee.carlrobert.service.NextEditResponse
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Dimension
|
||||
|
|
@ -128,10 +130,11 @@ class CodeSuggestionDiffViewer(
|
|||
popup.dispose()
|
||||
|
||||
application.executeOnPooledThread {
|
||||
grpcService?.getNextEdit(
|
||||
NextEditCoordinator.requestNextEdit(
|
||||
mainEditor,
|
||||
mainEditor.document.text,
|
||||
runReadAction { mainEditor.caretModel.offset },
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -194,8 +197,8 @@ class CodeSuggestionDiffViewer(
|
|||
)
|
||||
|
||||
if (popup.isVisible && !popup.isDisposed) {
|
||||
adjustPopupSize(popup, myEditor)
|
||||
popup.setLocation(adjustedLocation)
|
||||
adjustPopupSize(popup, myEditor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -386,4 +389,4 @@ fun createSuggestionDiffPopup(content: JComponent): JBPopup {
|
|||
.setCancelOnWindowDeactivation(false)
|
||||
.setCancelOnOtherWindowOpen(false)
|
||||
.createPopup()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import com.intellij.testFramework.LightVirtualFile
|
|||
import com.intellij.util.application
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys
|
||||
import ee.carlrobert.codegpt.codecompletions.CompletionProgressNotifier
|
||||
import ee.carlrobert.codegpt.codecompletions.edit.GrpcClientService
|
||||
import ee.carlrobert.codegpt.codecompletions.edit.NextEditCoordinator
|
||||
import ee.carlrobert.codegpt.util.EditorDiffUtil.createDiffRequest
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
|
|
@ -26,6 +26,7 @@ class PredictionService {
|
|||
fun acceptPrediction(editor: Editor) {
|
||||
val diffViewer = editor.getUserData(CodeGPTKeys.EDITOR_PREDICTION_DIFF_VIEWER)
|
||||
if (diffViewer != null && diffViewer.isVisible()) {
|
||||
|
||||
diffViewer.applyChanges()
|
||||
return
|
||||
}
|
||||
|
|
@ -36,10 +37,11 @@ class PredictionService {
|
|||
try {
|
||||
application.executeOnPooledThread {
|
||||
CompletionProgressNotifier.update(project, true)
|
||||
project.service<GrpcClientService>().getNextEdit(
|
||||
NextEditCoordinator.requestNextEdit(
|
||||
editor,
|
||||
editor.document.text,
|
||||
runReadAction { editor.caretModel.offset },
|
||||
false
|
||||
)
|
||||
}
|
||||
} catch (e: CancellationException) {
|
||||
|
|
@ -57,4 +59,4 @@ class PredictionService {
|
|||
service<DiffManager>().showDiff(project, diffRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,12 @@ class TriggerCustomPredictionAction : EditorAction(Handler()), HintManagerImpl.A
|
|||
private class Handler : EditorWriteActionHandler() {
|
||||
|
||||
override fun doExecute(editor: Editor, caret: Caret?, dataContext: DataContext?) {
|
||||
if (ModelSelectionService.getInstance()
|
||||
.getServiceForFeature(FeatureType.CODE_COMPLETION) != ServiceType.PROXYAI
|
||||
val nextEditModelProvider = ModelSelectionService.getInstance()
|
||||
.getServiceForFeature(FeatureType.NEXT_EDIT)
|
||||
if (!listOf(
|
||||
ServiceType.PROXYAI,
|
||||
ServiceType.INCEPTION
|
||||
).contains(nextEditModelProvider)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,10 @@ object LegacySettingsMigration {
|
|||
ServiceType.MISTRAL -> {
|
||||
ModelRegistry.DEVSTRAL_MEDIUM_2507
|
||||
}
|
||||
|
||||
ServiceType.INCEPTION -> {
|
||||
ModelRegistry.MERCURY_CODER
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger.warn("Failed to get legacy chat model for $serviceType", e)
|
||||
|
|
@ -152,10 +156,14 @@ object LegacySettingsMigration {
|
|||
ServiceType.MISTRAL -> {
|
||||
ModelRegistry.CODESTRAL_LATEST
|
||||
}
|
||||
|
||||
ServiceType.INCEPTION -> {
|
||||
ModelRegistry.MERCURY_CODER
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger.warn("Failed to get legacy code model for $serviceType", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ object ModelIcons {
|
|||
ServiceType.OLLAMA -> Icons.Ollama
|
||||
ServiceType.CUSTOM_OPENAI -> Icons.OpenAI
|
||||
ServiceType.LLAMA_CPP -> Icons.Llama
|
||||
ServiceType.INCEPTION -> Icons.Inception
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,14 @@ class ModelRegistry {
|
|||
FeatureType.CHAT, FeatureType.CODE_COMPLETION, FeatureType.AUTO_APPLY,
|
||||
FeatureType.COMMIT_MESSAGE, FeatureType.INLINE_EDIT, FeatureType.LOOKUP
|
||||
)
|
||||
),
|
||||
ServiceType.INCEPTION to ModelCapability(
|
||||
ServiceType.INCEPTION,
|
||||
setOf(
|
||||
FeatureType.CODE_COMPLETION,
|
||||
FeatureType.AUTO_APPLY,
|
||||
FeatureType.NEXT_EDIT
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -272,6 +280,7 @@ class ModelRegistry {
|
|||
addAll(getLlamaModels())
|
||||
addAll(getOllamaModels())
|
||||
addAll(getCustomOpenAIModels())
|
||||
addAll(getInceptionModels())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -283,6 +292,7 @@ class ModelRegistry {
|
|||
addAll(getLlamaModels())
|
||||
addAll(getCustomOpenAICodeModels())
|
||||
addAll(getOllamaModels())
|
||||
addAll(getInceptionModels())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +317,16 @@ class ModelRegistry {
|
|||
}
|
||||
|
||||
private fun getNextEditModels(): List<ModelSelection> {
|
||||
return listOf(ModelSelection(ServiceType.PROXYAI, ZETA, "Zeta"))
|
||||
return listOf(
|
||||
ModelSelection(ServiceType.PROXYAI, ZETA, "Zeta"),
|
||||
ModelSelection(ServiceType.INCEPTION, MERCURY_CODER, "Mercury Coder")
|
||||
)
|
||||
}
|
||||
|
||||
private fun getInceptionModels(): List<ModelSelection> {
|
||||
return listOf(
|
||||
ModelSelection(ServiceType.INCEPTION, MERCURY_CODER, "Mercury Coder")
|
||||
)
|
||||
}
|
||||
|
||||
fun getProxyAIChatModels(): List<ModelSelection> {
|
||||
|
|
@ -604,9 +623,11 @@ class ModelRegistry {
|
|||
// Llama.cpp default models
|
||||
const val LLAMA_3_2_3B_INSTRUCT = "llama-3.2-3b-instruct"
|
||||
|
||||
const val MERCURY_CODER = "mercury-coder"
|
||||
|
||||
@JvmStatic
|
||||
fun getInstance(): ModelRegistry {
|
||||
return ApplicationManager.getApplication().getService(ModelRegistry::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,7 +202,8 @@ class ModelSettingsForm(
|
|||
|
||||
private fun updateNextEditButtonState(codeCompletionProvider: ServiceType) {
|
||||
val nextEditButton = modelButtons[FeatureType.NEXT_EDIT] ?: return
|
||||
nextEditButton.isEnabled = codeCompletionProvider == ServiceType.PROXYAI
|
||||
nextEditButton.isEnabled =
|
||||
codeCompletionProvider == ServiceType.PROXYAI || codeCompletionProvider == ServiceType.INCEPTION
|
||||
}
|
||||
|
||||
fun isModified(): Boolean {
|
||||
|
|
@ -312,4 +313,4 @@ class ModelSettingsForm(
|
|||
override fun dispose() {
|
||||
messageBusConnection.disconnect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ class SettingsModelComboBoxAction(
|
|||
ServiceType.OPENAI,
|
||||
ServiceType.CUSTOM_OPENAI,
|
||||
ServiceType.GOOGLE,
|
||||
ServiceType.MISTRAL
|
||||
ServiceType.MISTRAL,
|
||||
ServiceType.INCEPTION
|
||||
)
|
||||
val hasCloudProviders = cloudProviders.any { groupedModels.containsKey(it) }
|
||||
|
||||
|
|
@ -245,4 +246,4 @@ class SettingsModelComboBoxAction(
|
|||
val llamaModel = LlamaModel.findByHuggingFaceModel(huggingFaceModel)
|
||||
return "${llamaModel.label} (${huggingFaceModel.parameterSize}B) / Q${huggingFaceModel.quantization}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
package ee.carlrobert.codegpt.settings.service
|
||||
|
||||
import com.intellij.openapi.options.Configurable
|
||||
import ee.carlrobert.codegpt.credentials.CredentialsStore
|
||||
import ee.carlrobert.codegpt.credentials.CredentialsStore.CredentialKey.InceptionApiKey
|
||||
import ee.carlrobert.codegpt.settings.service.inception.InceptionSettingsForm
|
||||
import javax.swing.JComponent
|
||||
|
||||
class InceptionServiceConfigurable : Configurable {
|
||||
|
||||
private lateinit var component: InceptionSettingsForm
|
||||
|
||||
override fun getDisplayName(): String {
|
||||
return "ProxyAI: Inception Service"
|
||||
}
|
||||
|
||||
override fun createComponent(): JComponent {
|
||||
component = InceptionSettingsForm()
|
||||
component.setApiKey(CredentialsStore.getCredential(InceptionApiKey))
|
||||
return component.getForm()
|
||||
}
|
||||
|
||||
override fun isModified(): Boolean {
|
||||
return component.getApiKey() != CredentialsStore.getCredential(InceptionApiKey)
|
||||
}
|
||||
|
||||
override fun apply() {
|
||||
CredentialsStore.setCredential(InceptionApiKey, component.getApiKey())
|
||||
ModelReplacementDialog.showDialogIfNeeded(ServiceType.INCEPTION)
|
||||
}
|
||||
|
||||
override fun reset() {
|
||||
component.setApiKey(CredentialsStore.getCredential(InceptionApiKey))
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,7 @@ class ServiceConfigurableComponent {
|
|||
"Mistral" to MistralServiceConfigurable::class.java,
|
||||
"LLaMA C/C++" to LlamaServiceConfigurable::class.java,
|
||||
"Ollama" to OllamaSettingsConfigurable::class.java,
|
||||
"Inception" to InceptionServiceConfigurable::class.java,
|
||||
).entries.forEach { (name, configurableClass) ->
|
||||
formBuilder.addComponent(ActionLink(name) {
|
||||
val context = service<DataManager>().getDataContext(it.source as ActionLink)
|
||||
|
|
@ -47,4 +48,4 @@ class ServiceConfigurableComponent {
|
|||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
package ee.carlrobert.codegpt.settings.service.inception
|
||||
|
||||
import com.intellij.openapi.components.BaseState
|
||||
import com.intellij.openapi.components.SimplePersistentStateComponent
|
||||
import com.intellij.openapi.components.State
|
||||
import com.intellij.openapi.components.Storage
|
||||
|
||||
@State(name = "CodeGPT_InceptionSettings", storages = [Storage("CodeGPT_InceptionSettings.xml")])
|
||||
class InceptionSettings : SimplePersistentStateComponent<InceptionSettingsState>(InceptionSettingsState())
|
||||
|
||||
class InceptionSettingsState : BaseState() {
|
||||
var codeCompletionsEnabled by property(true)
|
||||
var nextEditsEnabled by property(true)
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package ee.carlrobert.codegpt.settings.service.inception
|
||||
|
||||
import com.intellij.ui.components.JBPasswordField
|
||||
import com.intellij.util.ui.FormBuilder
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JPanel
|
||||
|
||||
class InceptionSettingsForm {
|
||||
private val apiKeyField = JBPasswordField()
|
||||
private val panel: JPanel = FormBuilder.createFormBuilder()
|
||||
.addLabeledComponent("API Key:", apiKeyField, 1, false)
|
||||
.addComponentFillVertically(JPanel(), 0)
|
||||
.panel
|
||||
|
||||
fun getForm(): JComponent = panel
|
||||
|
||||
fun getApiKey(): String? = String(apiKeyField.password)
|
||||
|
||||
fun setApiKey(value: String?) {
|
||||
apiKeyField.text = value ?: ""
|
||||
}
|
||||
}
|
||||
|
|
@ -105,15 +105,6 @@ class ResponseEditorPanel(
|
|||
replaceEditor(oldEditor, newState.editor)
|
||||
}
|
||||
|
||||
fun removeCurrentEditor() {
|
||||
runInEdt {
|
||||
removeAll()
|
||||
stateManager.clearCurrentState()
|
||||
revalidate()
|
||||
repaint()
|
||||
}
|
||||
}
|
||||
|
||||
fun applyCodeAsync(content: String, virtualFile: VirtualFile, editor: EditorEx, headerPanel: DefaultHeaderPanel? = null) {
|
||||
val eventSource = CompletionRequestService.getInstance().autoApplyAsync(
|
||||
AutoApplyParameters(content, virtualFile),
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ import com.intellij.openapi.vfs.VirtualFile
|
|||
import com.intellij.openapi.vfs.readText
|
||||
import com.intellij.ui.components.AnActionLink
|
||||
import com.intellij.util.ui.JBUI
|
||||
import ee.carlrobert.codegpt.settings.service.FeatureType
|
||||
import ee.carlrobert.codegpt.settings.service.ModelSelectionService
|
||||
import ee.carlrobert.codegpt.settings.service.ServiceType.INCEPTION
|
||||
import ee.carlrobert.codegpt.util.EditorUtil
|
||||
import javax.swing.JComponent
|
||||
|
||||
|
|
@ -33,6 +36,15 @@ class AutoApplyAction(
|
|||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
val autoApplyProvider =
|
||||
ModelSelectionService.getInstance().getServiceForFeature(FeatureType.AUTO_APPLY)
|
||||
if (autoApplyProvider == INCEPTION) {
|
||||
anActionLink.text = "Apply"
|
||||
anActionLink.isEnabled = false
|
||||
anActionLink.toolTipText = "Auto Apply is temporarily disabled for Inception provider"
|
||||
return
|
||||
}
|
||||
|
||||
if (virtualFile != null) {
|
||||
anActionLink.text = "Apply"
|
||||
anActionLink.isEnabled = true
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ object GitUtil {
|
|||
.filter { change ->
|
||||
change.virtualFile?.let { !it.fileType.isBinary } ?: false
|
||||
}
|
||||
.sortedBy { it.virtualFile?.timeStamp }
|
||||
.sortedByDescending { it.virtualFile?.timeStamp }
|
||||
|
||||
val patches = IdeaTextPatchBuilder.buildPatch(
|
||||
project, changes, repoRootPath, false, true
|
||||
|
|
@ -52,7 +52,7 @@ object GitUtil {
|
|||
UnifiedDiffWriter.write(
|
||||
null, repoRootPath, patches, diffWriter, "\n\n", null, null
|
||||
)
|
||||
diffWriter.toString().cleanDiff().truncateText(1024, false)
|
||||
diffWriter.toString().cleanDiff().truncateText(1024, true)
|
||||
} catch (e: VcsException) {
|
||||
logger.error("Failed to get git context", e)
|
||||
null
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@
|
|||
<applicationConfigurable id="settings.codegpt.services.ollama" parentId="settings.codegpt.services"
|
||||
displayName="Ollama (Offline)"
|
||||
instance="ee.carlrobert.codegpt.settings.service.ollama.OllamaSettingsConfigurable"/>
|
||||
<applicationConfigurable id="settings.codegpt.services.inception" parentId="settings.codegpt.services"
|
||||
displayName="Inception"
|
||||
instance="ee.carlrobert.codegpt.settings.service.InceptionServiceConfigurable"/>
|
||||
<applicationConfigurable id="settings.codegpt.models" parentId="settings.codegpt" bundle="messages.codegpt"
|
||||
key="settings.models.displayName"
|
||||
instance="ee.carlrobert.codegpt.settings.models.ModelSettingsConfigurable"/>
|
||||
|
|
@ -87,6 +90,7 @@
|
|||
<applicationService serviceImplementation="ee.carlrobert.codegpt.settings.service.mistral.MistralSettings"/>
|
||||
<applicationService serviceImplementation="ee.carlrobert.codegpt.settings.service.llama.LlamaSettings"/>
|
||||
<applicationService serviceImplementation="ee.carlrobert.codegpt.settings.service.ollama.OllamaSettings"/>
|
||||
<applicationService serviceImplementation="ee.carlrobert.codegpt.settings.service.inception.InceptionSettings"/>
|
||||
<applicationService serviceImplementation="ee.carlrobert.codegpt.settings.models.ModelSettings"/>
|
||||
<applicationService serviceImplementation="ee.carlrobert.codegpt.settings.IncludedFilesSettings"/>
|
||||
<applicationService serviceImplementation="ee.carlrobert.codegpt.settings.advanced.AdvancedSettings"/>
|
||||
|
|
|
|||
12
src/main/resources/icons/inception.svg
Normal file
12
src/main/resources/icons/inception.svg
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 28 28" fill="none">
|
||||
<g clip-path="url(#svg1378540956_510_clip0_1_1506)">
|
||||
<path d="M17.0547 0.372066H8.52652L-0.00165176 8.90024V17.4284H8.52652V8.90024H17.0547V0.372066Z" fill="#1A1C20"/>
|
||||
<path d="M10.1992 27.6279H18.7274L27.2556 19.0998V10.5716H18.7274V19.0998H10.1992V27.6279Z" fill="#1A1C20"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="svg1378540956_510_clip0_1_1506">
|
||||
<rect width="27.2559" height="27.2559" fill="white" transform="translate(0 0.37207)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 577 B |
12
src/main/resources/icons/inception_dark.svg
Normal file
12
src/main/resources/icons/inception_dark.svg
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 28 28" fill="none">
|
||||
<g clip-path="url(#svg1378540956_510_clip0_1_1506)">
|
||||
<path d="M17.0547 0.372066H8.52652L-0.00165176 8.90024V17.4284H8.52652V8.90024H17.0547V0.372066Z" fill="white"/>
|
||||
<path d="M10.1992 27.6279H18.7274L27.2556 19.0998V10.5716H18.7274V19.0998H10.1992V27.6279Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="svg1378540956_510_clip0_1_1506">
|
||||
<rect width="27.2559" height="27.2559" fill="white" transform="translate(0 0.37207)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 573 B |
|
|
@ -254,6 +254,7 @@ service.anthropic.title=Anthropic
|
|||
service.azure.title=Azure
|
||||
service.google.title=Google
|
||||
service.mistral.title=Mistral
|
||||
service.inception.title=Inception Labs
|
||||
service.llama.title=LLaMA C/C++
|
||||
service.ollama.title=Ollama
|
||||
validation.error.model.notExists='%s' is not available, please select another model
|
||||
|
|
|
|||
|
|
@ -77,31 +77,31 @@ class DefaultToolwindowChatCompletionRequestHandlerTest : IntegrationTest() {
|
|||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
conversation.addMessage(Message("Ping", "Pong"))
|
||||
expectLlama(StreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path).isEqualTo("/completion")
|
||||
assertThat(request.uri.path).isEqualTo("/v1/chat/completions")
|
||||
val guidelines = getResourceContent("/prompts/persona/psi-navigation-guidelines.txt")
|
||||
val expectedSystem = "TEST_SYSTEM_PROMPT\n$guidelines"
|
||||
assertThat(request.body)
|
||||
.extracting(
|
||||
"prompt",
|
||||
"n_predict",
|
||||
"stream"
|
||||
"model",
|
||||
"messages"
|
||||
)
|
||||
.containsExactly(
|
||||
LLAMA.buildPrompt(
|
||||
expectedSystem,
|
||||
"TEST_PROMPT",
|
||||
conversation.messages
|
||||
),
|
||||
99,
|
||||
true
|
||||
HuggingFaceModel.CODE_LLAMA_7B_Q4.code,
|
||||
listOf(
|
||||
mapOf("role" to "system", "content" to expectedSystem),
|
||||
mapOf("role" to "user", "content" to "Ping"),
|
||||
mapOf("role" to "assistant", "content" to "Pong"),
|
||||
mapOf("role" to "user", "content" to "TEST_PROMPT")
|
||||
)
|
||||
)
|
||||
listOf<String?>(
|
||||
jsonMapResponse("content", "Hel"),
|
||||
jsonMapResponse("content", "lo!"),
|
||||
listOf(
|
||||
jsonMapResponse(
|
||||
e("content", ""),
|
||||
e("stop", true)
|
||||
)
|
||||
"choices",
|
||||
jsonArray(jsonMap("delta", jsonMap("role", "assistant")))
|
||||
),
|
||||
jsonMapResponse("choices", jsonArray(jsonMap("delta", jsonMap("content", "Hel")))),
|
||||
jsonMapResponse("choices", jsonArray(jsonMap("delta", jsonMap("content", "lo")))),
|
||||
jsonMapResponse("choices", jsonArray(jsonMap("delta", jsonMap("content", "!"))))
|
||||
)
|
||||
})
|
||||
val requestHandler =
|
||||
|
|
|
|||
|
|
@ -115,15 +115,16 @@ class ModelRegistryTest : IntegrationTest() {
|
|||
ServiceType.MISTRAL,
|
||||
ServiceType.OLLAMA,
|
||||
ServiceType.LLAMA_CPP,
|
||||
ServiceType.CUSTOM_OPENAI
|
||||
ServiceType.CUSTOM_OPENAI,
|
||||
ServiceType.INCEPTION
|
||||
)
|
||||
assertThat(result).doesNotContain(ServiceType.ANTHROPIC, ServiceType.GOOGLE)
|
||||
}
|
||||
|
||||
fun `test getProvidersForFeature with next edit returns proxyai only`() {
|
||||
fun `test getProvidersForFeature with next edit returns proxyai and inception`() {
|
||||
val result = modelRegistry.getProvidersForFeature(FeatureType.NEXT_EDIT)
|
||||
|
||||
assertThat(result).containsExactly(ServiceType.PROXYAI)
|
||||
assertThat(result).containsExactlyInAnyOrder(ServiceType.PROXYAI, ServiceType.INCEPTION)
|
||||
}
|
||||
|
||||
fun `test isFeatureSupportedByProvider with valid chat provider returns true`() {
|
||||
|
|
@ -182,4 +183,4 @@ class ModelRegistryTest : IntegrationTest() {
|
|||
|
||||
assertThat(result).isNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -401,41 +401,30 @@ class ChatToolWindowTabPanelTest : IntegrationTest() {
|
|||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val panel = ChatToolWindowTabPanel(project, conversation)
|
||||
expectLlama(StreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path).isEqualTo("/completion")
|
||||
assertThat(request.uri.path).isEqualTo("/v1/chat/completions")
|
||||
val expectedSystem = getResourceContent("/prompts/persona/psi-navigation-guidelines.txt").let { g ->
|
||||
"TEST_SYSTEM_PROMPT\n$g"
|
||||
}
|
||||
assertThat(request.body)
|
||||
.extracting(
|
||||
"prompt",
|
||||
"n_predict",
|
||||
"stream",
|
||||
"temperature",
|
||||
"top_k",
|
||||
"top_p",
|
||||
"min_p",
|
||||
"repeat_penalty"
|
||||
"model",
|
||||
"messages"
|
||||
)
|
||||
.containsExactly(
|
||||
LLAMA.buildPrompt(
|
||||
(getResourceContent("/prompts/persona/psi-navigation-guidelines.txt").let { g ->
|
||||
"TEST_SYSTEM_PROMPT\n$g"
|
||||
}),
|
||||
"TEST_PROMPT",
|
||||
conversation.messages
|
||||
),
|
||||
configurationState.maxTokens,
|
||||
true,
|
||||
configurationState.temperature.toDouble(),
|
||||
llamaSettings.topK,
|
||||
llamaSettings.topP,
|
||||
llamaSettings.minP,
|
||||
llamaSettings.repeatPenalty
|
||||
HuggingFaceModel.CODE_LLAMA_7B_Q4.code,
|
||||
listOf(
|
||||
mapOf("role" to "system", "content" to expectedSystem),
|
||||
mapOf("role" to "user", "content" to "TEST_PROMPT")
|
||||
)
|
||||
)
|
||||
listOf<String?>(
|
||||
jsonMapResponse("content", "Hel"),
|
||||
jsonMapResponse("content", "lo!"),
|
||||
listOf(
|
||||
jsonMapResponse(
|
||||
e("content", ""),
|
||||
e("stop", true)
|
||||
)
|
||||
"choices",
|
||||
jsonArray(jsonMap("delta", jsonMap("role", "assistant")))
|
||||
),
|
||||
jsonMapResponse("choices", jsonArray(jsonMap("delta", jsonMap("content", "Hel")))),
|
||||
jsonMapResponse("choices", jsonArray(jsonMap("delta", jsonMap("content", "lo")))),
|
||||
jsonMapResponse("choices", jsonArray(jsonMap("delta", jsonMap("content", "!"))))
|
||||
)
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue