mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-19 07:54:46 +00:00
feat: support DeepSeek R1 and V3 models
This commit is contained in:
parent
89a3b669c5
commit
4e149c54de
13 changed files with 300 additions and 64 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 0541f06296753dbc59a57379eb54cec865a4c9f9
|
||||
Subproject commit d6d24cd9ed6d0b9558643dcc28f2124bef488c52
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
package ee.carlrobert.codegpt;
|
||||
|
||||
import static java.io.File.separator;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.intellij.ide.plugins.PluginManagerCore;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.extensions.PluginId;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
|
@ -26,18 +26,18 @@ public final class CodeGPTPlugin {
|
|||
}
|
||||
|
||||
public static @NotNull String getPluginOptionsPath() {
|
||||
return PathManager.getOptionsPath() + File.separator + "CodeGPT";
|
||||
return PathManager.getOptionsPath() + separator + "CodeGPT";
|
||||
}
|
||||
|
||||
public static @NotNull String getIndexStorePath() {
|
||||
return getPluginOptionsPath() + File.separator + "indexes";
|
||||
return getPluginOptionsPath() + separator + "indexes";
|
||||
}
|
||||
|
||||
public static @NotNull String getLlamaSourcePath() {
|
||||
return getPluginBasePath() + File.separator + "llama.cpp";
|
||||
return getPluginBasePath() + separator + "llama.cpp";
|
||||
}
|
||||
|
||||
public static @NotNull String getProjectIndexStorePath(@NotNull Project project) {
|
||||
return getIndexStorePath() + File.separator + project.getName();
|
||||
return getIndexStorePath() + separator + project.getName();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,17 @@ public enum HuggingFaceModel {
|
|||
DEEPSEEK_CODER_33B_Q5(33, 5, "deepseek-coder-33b-instruct-GGUF",
|
||||
"deepseek-coder-33b-instruct.Q5_K_M.gguf", 23.5),
|
||||
|
||||
DEEPSEEK_R1_1_5B_Q6(1, 6, "DeepSeek-R1-Distill-Qwen-1.5B-GGUF",
|
||||
"DeepSeek-R1-Distill-Qwen-1.5B-Q6_K.gguf", "bartowski", 1.89),
|
||||
DEEPSEEK_R1_7B_Q4(7, 4, "DeepSeek-R1-Distill-Qwen-7B-GGUF",
|
||||
"DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf", "bartowski", 4.68),
|
||||
DEEPSEEK_R1_7B_Q6(7, 6, "DeepSeek-R1-Distill-Qwen-7B-GGUF",
|
||||
"DeepSeek-R1-Distill-Qwen-7B-Q6_K.gguf", "bartowski", 6.25),
|
||||
DEEPSEEK_R1_14B_Q4(14, 4, "DeepSeek-R1-Distill-Qwen-14B-GGUF",
|
||||
"DeepSeek-R1-Distill-Qwen-14B-Q4_K_M.gguf", "bartowski", 8.99),
|
||||
DEEPSEEK_R1_14B_Q6(14, 6, "DeepSeek-R1-Distill-Qwen-14B-GGUF",
|
||||
"DeepSeek-R1-Distill-Qwen-14B-Q6_K.gguf", "bartowski", 12.12),
|
||||
|
||||
PHIND_CODE_LLAMA_34B_Q3(34, 3, "Phind-CodeLlama-34B-v2-GGUF",
|
||||
"phind-codellama-34b-v2.Q3_K_M.gguf"),
|
||||
PHIND_CODE_LLAMA_34B_Q4(34, 4, "Phind-CodeLlama-34B-v2-GGUF",
|
||||
|
|
|
|||
|
|
@ -64,6 +64,20 @@ public enum LlamaModel {
|
|||
HuggingFaceModel.DEEPSEEK_CODER_33B_Q3,
|
||||
HuggingFaceModel.DEEPSEEK_CODER_33B_Q4,
|
||||
HuggingFaceModel.DEEPSEEK_CODER_33B_Q5)),
|
||||
DEEPSEEK_R1(
|
||||
"Deepseek R1",
|
||||
"DeepSeek-R1-Zero, a model trained via large-scale reinforcement learning (RL) "
|
||||
+ "without supervised fine-tuning (SFT) as a preliminary step, demonstrated remarkable "
|
||||
+ "performance on reasoning. DeepSeek-R1 achieves performance comparable to OpenAI-o1 "
|
||||
+ "across math, code, and reasoning tasks.",
|
||||
PromptTemplate.DEEPSEEK_R1,
|
||||
InfillPromptTemplate.DEEPSEEK_CODER,
|
||||
List.of(
|
||||
HuggingFaceModel.DEEPSEEK_R1_1_5B_Q6,
|
||||
HuggingFaceModel.DEEPSEEK_R1_7B_Q4,
|
||||
HuggingFaceModel.DEEPSEEK_R1_7B_Q6,
|
||||
HuggingFaceModel.DEEPSEEK_R1_14B_Q4,
|
||||
HuggingFaceModel.DEEPSEEK_R1_14B_Q6)),
|
||||
PHIND_CODE_LLAMA(
|
||||
"Phind Code Llama",
|
||||
"This model is fine-tuned from Phind-CodeLlama-34B-v1 on an additional 1.5B tokens "
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ public final class LlamaServerAgent implements Disposable {
|
|||
|
||||
private static final Logger LOG = Logger.getInstance(LlamaServerAgent.class);
|
||||
|
||||
private @Nullable OSProcessHandler makeProcessHandler;
|
||||
private @Nullable OSProcessHandler makeSetupProcessHandler;
|
||||
private @Nullable OSProcessHandler makeBuildProcessHandler;
|
||||
private @Nullable OSProcessHandler startServerProcessHandler;
|
||||
private ServerProgressPanel activeServerProgressPanel;
|
||||
private boolean stoppedByUser;
|
||||
|
|
@ -49,11 +50,44 @@ public final class LlamaServerAgent implements Disposable {
|
|||
stoppedByUser = false;
|
||||
serverProgressPanel.displayText(
|
||||
CodeGPTBundle.get("llamaServerAgent.buildingProject.description"));
|
||||
makeProcessHandler = new OSProcessHandler(
|
||||
getMakeCommandLine(params));
|
||||
makeProcessHandler.addProcessListener(
|
||||
getMakeProcessListener(params, onSuccess, onServerStopped));
|
||||
makeProcessHandler.startNotify();
|
||||
|
||||
makeSetupProcessHandler = new OSProcessHandler(getCMakeSetupCommandLine(params));
|
||||
makeSetupProcessHandler.addProcessListener(new ProcessAdapter() {
|
||||
private final List<String> errorLines = new CopyOnWriteArrayList<>();
|
||||
|
||||
@Override
|
||||
public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) {
|
||||
if (ProcessOutputType.isStderr(outputType)) {
|
||||
errorLines.add(event.getText());
|
||||
return;
|
||||
}
|
||||
LOG.info(event.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processTerminated(@NotNull ProcessEvent event) {
|
||||
int exitCode = event.getExitCode();
|
||||
LOG.info(format("CMake setup exited with code %d", exitCode));
|
||||
if (stoppedByUser) {
|
||||
onServerStopped.accept(activeServerProgressPanel);
|
||||
return;
|
||||
}
|
||||
if (exitCode != 0) {
|
||||
showServerError(String.join(",", errorLines), onServerStopped);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
makeBuildProcessHandler = new OSProcessHandler(getCMakeBuildCommandLine(params));
|
||||
makeBuildProcessHandler.addProcessListener(
|
||||
getMakeProcessListener(params, onSuccess, onServerStopped));
|
||||
makeBuildProcessHandler.startNotify();
|
||||
} catch (ExecutionException e) {
|
||||
showServerError(e.getMessage(), onServerStopped);
|
||||
}
|
||||
}
|
||||
});
|
||||
makeSetupProcessHandler.startNotify();
|
||||
} catch (ExecutionException e) {
|
||||
showServerError(e.getMessage(), onServerStopped);
|
||||
}
|
||||
|
|
@ -62,8 +96,8 @@ public final class LlamaServerAgent implements Disposable {
|
|||
|
||||
public void stopAgent() {
|
||||
stoppedByUser = true;
|
||||
if (makeProcessHandler != null) {
|
||||
makeProcessHandler.destroyProcess();
|
||||
if (makeSetupProcessHandler != null) {
|
||||
makeSetupProcessHandler.destroyProcess();
|
||||
}
|
||||
if (startServerProcessHandler != null) {
|
||||
startServerProcessHandler.destroyProcess();
|
||||
|
|
@ -71,9 +105,9 @@ public final class LlamaServerAgent implements Disposable {
|
|||
}
|
||||
|
||||
public boolean isServerRunning() {
|
||||
return (makeProcessHandler != null
|
||||
&& makeProcessHandler.isStartNotified()
|
||||
&& !makeProcessHandler.isProcessTerminated())
|
||||
return (makeSetupProcessHandler != null
|
||||
&& makeSetupProcessHandler.isStartNotified()
|
||||
&& !makeSetupProcessHandler.isProcessTerminated())
|
||||
|| (startServerProcessHandler != null
|
||||
&& startServerProcessHandler.isStartNotified()
|
||||
&& !startServerProcessHandler.isProcessTerminated());
|
||||
|
|
@ -147,25 +181,14 @@ public final class LlamaServerAgent implements Disposable {
|
|||
|
||||
@Override
|
||||
public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) {
|
||||
if (ProcessOutputType.isStderr(outputType)) {
|
||||
errorLines.add(event.getText());
|
||||
}
|
||||
LOG.info(event.getText());
|
||||
|
||||
if (ProcessOutputType.isStdout(outputType)) {
|
||||
LOG.info(event.getText());
|
||||
// TODO: Use proper successful boot up validation
|
||||
if (event.getText().contains("server is listening")) {
|
||||
LOG.info("Server up and running!");
|
||||
|
||||
try {
|
||||
var serverMessage = objectMapper.readValue(event.getText(), LlamaServerMessage.class);
|
||||
// hack
|
||||
if ("HTTP server listening".equals(serverMessage.msg())) {
|
||||
LOG.info("Server up and running!");
|
||||
|
||||
LlamaSettings.getCurrentState().setServerPort(port);
|
||||
onSuccess.run();
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// ignore
|
||||
}
|
||||
LlamaSettings.getCurrentState().setServerPort(port);
|
||||
onSuccess.run();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -177,20 +200,32 @@ public final class LlamaServerAgent implements Disposable {
|
|||
OverlayUtil.showClosableBalloon(errorText, MessageType.ERROR, activeServerProgressPanel);
|
||||
}
|
||||
|
||||
private static GeneralCommandLine getMakeCommandLine(LlamaServerStartupParams params) {
|
||||
GeneralCommandLine commandLine = new GeneralCommandLine().withCharset(StandardCharsets.UTF_8);
|
||||
commandLine.setExePath("make");
|
||||
commandLine.withWorkDirectory(CodeGPTPlugin.getLlamaSourcePath());
|
||||
commandLine.addParameters("-j");
|
||||
commandLine.addParameters(params.additionalBuildParameters());
|
||||
commandLine.withEnvironment(params.additionalEnvironmentVariables());
|
||||
commandLine.setRedirectErrorStream(false);
|
||||
return commandLine;
|
||||
private static GeneralCommandLine getCMakeSetupCommandLine(LlamaServerStartupParams params) {
|
||||
GeneralCommandLine cmakeSetupCommand = new GeneralCommandLine().withCharset(
|
||||
StandardCharsets.UTF_8);
|
||||
cmakeSetupCommand.setExePath("cmake");
|
||||
cmakeSetupCommand.withWorkDirectory(CodeGPTPlugin.getLlamaSourcePath());
|
||||
cmakeSetupCommand.addParameters("-B", "build");
|
||||
cmakeSetupCommand.withEnvironment(params.additionalEnvironmentVariables());
|
||||
cmakeSetupCommand.setRedirectErrorStream(false);
|
||||
return cmakeSetupCommand;
|
||||
}
|
||||
|
||||
private static GeneralCommandLine getCMakeBuildCommandLine(LlamaServerStartupParams params) {
|
||||
GeneralCommandLine cmakeBuildCommand = new GeneralCommandLine().withCharset(
|
||||
StandardCharsets.UTF_8);
|
||||
cmakeBuildCommand.setExePath("cmake");
|
||||
cmakeBuildCommand.withWorkDirectory(CodeGPTPlugin.getLlamaSourcePath());
|
||||
cmakeBuildCommand.addParameters("--build", "build", "--config", "Release", "-t", "llama-server",
|
||||
"-j", "4");
|
||||
cmakeBuildCommand.withEnvironment(params.additionalEnvironmentVariables());
|
||||
cmakeBuildCommand.setRedirectErrorStream(false);
|
||||
return cmakeBuildCommand;
|
||||
}
|
||||
|
||||
private GeneralCommandLine getServerCommandLine(LlamaServerStartupParams params) {
|
||||
GeneralCommandLine commandLine = new GeneralCommandLine().withCharset(StandardCharsets.UTF_8);
|
||||
commandLine.setExePath("./server");
|
||||
commandLine.setExePath("./build/bin/llama-server");
|
||||
commandLine.withWorkDirectory(CodeGPTPlugin.getLlamaSourcePath());
|
||||
commandLine.addParameters(
|
||||
"-m", params.modelPath(),
|
||||
|
|
@ -210,8 +245,8 @@ public final class LlamaServerAgent implements Disposable {
|
|||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (makeProcessHandler != null && !makeProcessHandler.isProcessTerminated()) {
|
||||
makeProcessHandler.destroyProcess();
|
||||
if (makeSetupProcessHandler != null && !makeSetupProcessHandler.isProcessTerminated()) {
|
||||
makeSetupProcessHandler.destroyProcess();
|
||||
}
|
||||
if (startServerProcessHandler != null && !startServerProcessHandler.isProcessTerminated()) {
|
||||
startServerProcessHandler.destroyProcess();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import static java.util.Collections.emptyList;
|
|||
|
||||
import ee.carlrobert.codegpt.conversations.message.Message;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public enum PromptTemplate {
|
||||
|
||||
|
|
@ -237,6 +238,23 @@ public enum PromptTemplate {
|
|||
.toString();
|
||||
}
|
||||
},
|
||||
DEEPSEEK_R1("DeepSeek R1") {
|
||||
@Override
|
||||
public String buildPrompt(String systemPrompt, String userPrompt, List<Message> history) {
|
||||
var historyString = history.stream()
|
||||
.map(it -> {
|
||||
String response = it.getResponse();
|
||||
if (response.startsWith("<think>")) {
|
||||
response = response.replaceAll("(?s)<think>.*?</think>", "").trim();
|
||||
}
|
||||
return String.format("User:\n%s\n\nAssistant:\n%s", it.getPrompt(), response);
|
||||
})
|
||||
.collect(Collectors.joining("\n\n"));
|
||||
|
||||
return "<|begin▁of▁sentence|>%s<|User|>History:\n%s\n\nUser:\n%s<|Assistant|>"
|
||||
.formatted(systemPrompt, historyString, userPrompt);
|
||||
}
|
||||
},
|
||||
DEEPSEEK_CODER("DeepSeek Coder") {
|
||||
@Override
|
||||
public String buildPrompt(String systemPrompt, String userPrompt, List<Message> history) {
|
||||
|
|
|
|||
|
|
@ -225,7 +225,6 @@ public class ChatToolWindowTabPanel implements Disposable {
|
|||
panel.addCopyAction(() -> CopyAction.copyToClipboard(message.getResponse()));
|
||||
panel.addContent(new ChatMessageResponseBody(
|
||||
project,
|
||||
true,
|
||||
false,
|
||||
message.isWebSearchIncluded(),
|
||||
fileContextIncluded || message.getDocumentationDetails() != null,
|
||||
|
|
|
|||
|
|
@ -37,17 +37,18 @@ import ee.carlrobert.codegpt.events.WebSearchEventDetails;
|
|||
import ee.carlrobert.codegpt.settings.GeneralSettingsConfigurable;
|
||||
import ee.carlrobert.codegpt.telemetry.TelemetryAction;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.StreamParser;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.ThinkingOutputParser;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.editor.ResponseEditorPanel;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.editor.actions.CopyAction;
|
||||
import ee.carlrobert.codegpt.toolwindow.ui.ResponseBodyProgressPanel;
|
||||
import ee.carlrobert.codegpt.toolwindow.ui.WebpageList;
|
||||
import ee.carlrobert.codegpt.ui.OverlayUtil;
|
||||
import ee.carlrobert.codegpt.ui.ThoughtProcessPanel;
|
||||
import ee.carlrobert.codegpt.ui.UIUtil;
|
||||
import ee.carlrobert.codegpt.util.EditorUtil;
|
||||
import ee.carlrobert.codegpt.util.MarkdownUtil;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JEditorPane;
|
||||
|
|
@ -62,6 +63,7 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
private final Project project;
|
||||
private final Disposable parentDisposable;
|
||||
private final StreamParser streamParser;
|
||||
private final ThinkingOutputParser thinkingOutputParser;
|
||||
private final boolean readOnly;
|
||||
private final DefaultListModel<WebSearchEventDetails> webpageListModel = new DefaultListModel<>();
|
||||
private final WebpageList webpageList = new WebpageList(webpageListModel);
|
||||
|
|
@ -71,12 +73,11 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
private JPanel webpageListPanel;
|
||||
|
||||
public ChatMessageResponseBody(Project project, Disposable parentDisposable) {
|
||||
this(project, false, false, false, false, parentDisposable);
|
||||
this(project, false, false, false, parentDisposable);
|
||||
}
|
||||
|
||||
public ChatMessageResponseBody(
|
||||
Project project,
|
||||
boolean withGhostText,
|
||||
boolean readOnly,
|
||||
boolean webSearchIncluded,
|
||||
boolean withProgress,
|
||||
|
|
@ -84,6 +85,7 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
this.project = project;
|
||||
this.parentDisposable = parentDisposable;
|
||||
this.streamParser = new StreamParser();
|
||||
this.thinkingOutputParser = new ThinkingOutputParser();
|
||||
this.readOnly = readOnly;
|
||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||
setOpaque(false);
|
||||
|
|
@ -96,12 +98,6 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
webpageListPanel = createWebpageListPanel(webpageList);
|
||||
add(webpageListPanel);
|
||||
}
|
||||
|
||||
if (withGhostText) {
|
||||
prepareProcessingText(!readOnly);
|
||||
currentlyProcessedTextPane.setText(
|
||||
"<html><p style=\"margin-top: 4px; margin-bottom: 8px;\">‍</p></html>");
|
||||
}
|
||||
}
|
||||
|
||||
public ChatMessageResponseBody withResponse(@NotNull String response) {
|
||||
|
|
@ -119,6 +115,29 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
}
|
||||
|
||||
public void updateMessage(String partialMessage) {
|
||||
thinkingOutputParser.processChunk(partialMessage);
|
||||
|
||||
var thoughtProcessPanel = (ThoughtProcessPanel) Stream.of(getComponents())
|
||||
.filter(it -> it instanceof ThoughtProcessPanel)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (thinkingOutputParser.isThinking()) {
|
||||
progressPanel.setVisible(false);
|
||||
|
||||
if (thoughtProcessPanel == null) {
|
||||
thoughtProcessPanel = new ThoughtProcessPanel();
|
||||
add(thoughtProcessPanel);
|
||||
} else {
|
||||
thoughtProcessPanel.updateText(thinkingOutputParser.getThoughtProcess());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (thoughtProcessPanel != null && !thoughtProcessPanel.getFinished()) {
|
||||
thoughtProcessPanel.setFinished();
|
||||
}
|
||||
|
||||
for (var item : streamParser.parse(partialMessage)) {
|
||||
processResponse(item.response(), CODE.equals(item.type()), true);
|
||||
}
|
||||
|
|
@ -240,6 +259,19 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
}
|
||||
}
|
||||
|
||||
private void processThinkingOutput(String thoughtProcess) {
|
||||
Stream.of(getComponents())
|
||||
.filter(it -> it instanceof ThoughtProcessPanel)
|
||||
.findFirst()
|
||||
.ifPresentOrElse(thoughtProcessPanel -> {
|
||||
((ThoughtProcessPanel) thoughtProcessPanel).updateText(thoughtProcess);
|
||||
}, () -> {
|
||||
add(new ThoughtProcessPanel());
|
||||
revalidate();
|
||||
repaint();
|
||||
});
|
||||
}
|
||||
|
||||
private void processCode(String markdownCode) {
|
||||
var document = Parser.builder().build().parse(markdownCode);
|
||||
var child = document.getChildOfType(FencedCodeBlock.class);
|
||||
|
|
|
|||
|
|
@ -219,8 +219,16 @@ class OpenAIRequestFactory : CompletionRequestFactory {
|
|||
} else {
|
||||
messages.add(OpenAIChatCompletionStandardMessage("user", prevMessage.prompt))
|
||||
}
|
||||
|
||||
var response = prevMessage.response ?: ""
|
||||
if (response.startsWith("<think>")) {
|
||||
response = response
|
||||
.replace("(?s)<think>.*?</think>".toRegex(), "")
|
||||
.trim { it <= ' ' }
|
||||
}
|
||||
|
||||
messages.add(
|
||||
OpenAIChatCompletionStandardMessage("assistant", prevMessage.response)
|
||||
OpenAIChatCompletionStandardMessage("assistant", response)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,9 +17,8 @@ object CodeGPTAvailableModels {
|
|||
CodeGPTModel("o1-mini", "o1-mini", Icons.OpenAI, INDIVIDUAL),
|
||||
CodeGPTModel("GPT-4o", "gpt-4o", Icons.OpenAI, INDIVIDUAL),
|
||||
CodeGPTModel("Claude 3.5 Sonnet", "claude-3.5-sonnet", Icons.Anthropic, INDIVIDUAL),
|
||||
CodeGPTModel("DeepSeek R1", "deepseek-r1", Icons.DeepSeek, INDIVIDUAL),
|
||||
CodeGPTModel("Gemini 1.5 Pro", "gemini-pro-1.5", Icons.Google, INDIVIDUAL),
|
||||
CodeGPTModel("Qwen 2.5 Coder (32B)", "qwen-2.5-32b-chat", Icons.Qwen, FREE),
|
||||
CodeGPTModel("Llama 3.1 (405B)", "llama-3.1-405b", Icons.Meta, FREE),
|
||||
CodeGPTModel("DeepSeek Coder V2 - FREE", "deepseek-coder-v2", Icons.DeepSeek, ANONYMOUS),
|
||||
CodeGPTModel("GPT-4o mini - FREE", "gpt-4o-mini", Icons.OpenAI, ANONYMOUS),
|
||||
)
|
||||
|
|
@ -28,7 +27,8 @@ object CodeGPTAvailableModels {
|
|||
CodeGPTModel("o1-mini", "o1-mini", Icons.OpenAI, INDIVIDUAL),
|
||||
CodeGPTModel("GPT-4o", "gpt-4o", Icons.OpenAI, INDIVIDUAL),
|
||||
CodeGPTModel("Claude 3.5 Sonnet", "claude-3.5-sonnet", Icons.Anthropic, INDIVIDUAL),
|
||||
CodeGPTModel("Gemini 1.5 Pro", "gemini-pro-1.5", Icons.Google, INDIVIDUAL),
|
||||
CodeGPTModel("DeepSeek R1", "deepseek-r1", Icons.DeepSeek, INDIVIDUAL),
|
||||
CodeGPTModel("DeepSeek V3", "deepseek-v3", Icons.DeepSeek, FREE),
|
||||
CodeGPTModel("Qwen 2.5 Coder (32B)", "qwen-2.5-32b-chat", Icons.Qwen, FREE),
|
||||
CodeGPTModel("Llama 3.1 (405B)", "llama-3.1-405b", Icons.Meta, FREE),
|
||||
CodeGPTModel("DeepSeek Coder V2", "deepseek-coder-v2", Icons.DeepSeek, ANONYMOUS),
|
||||
|
|
@ -38,9 +38,9 @@ object CodeGPTAvailableModels {
|
|||
CodeGPTModel("o1-mini", "o1-mini", Icons.OpenAI, INDIVIDUAL),
|
||||
CodeGPTModel("GPT-4o", "gpt-4o", Icons.OpenAI, INDIVIDUAL),
|
||||
CodeGPTModel("Claude 3.5 Sonnet", "claude-3.5-sonnet", Icons.Anthropic, INDIVIDUAL),
|
||||
CodeGPTModel("DeepSeek R1", "deepseek-r1", Icons.DeepSeek, INDIVIDUAL),
|
||||
CodeGPTModel("DeepSeek V3", "deepseek-v3", Icons.DeepSeek, FREE),
|
||||
CodeGPTModel("Gemini 1.5 Pro", "gemini-pro-1.5", Icons.Google, INDIVIDUAL),
|
||||
CodeGPTModel("Qwen 2.5 Coder (32B)", "qwen-2.5-32b-chat", Icons.Qwen, FREE),
|
||||
CodeGPTModel("Llama 3.1 (405B)", "llama-3.1-405b", Icons.Meta, FREE),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -54,6 +54,8 @@ object CodeGPTAvailableModels {
|
|||
CodeGPTModel("Gemini 1.5 Pro", "gemini-pro-1.5", Icons.Google, INDIVIDUAL),
|
||||
CodeGPTModel("Qwen 2.5 Coder (32B)", "qwen-2.5-32b-chat", Icons.Qwen, FREE),
|
||||
CodeGPTModel("Llama 3.1 (405B)", "llama-3.1-405b", Icons.Meta, FREE),
|
||||
CodeGPTModel("DeepSeek R1", "deepseek-r1", Icons.DeepSeek, INDIVIDUAL),
|
||||
CodeGPTModel("DeepSeek V3", "deepseek-v3", Icons.DeepSeek, FREE),
|
||||
CodeGPTModel("DeepSeek Coder V2", "deepseek-coder-v2", Icons.DeepSeek, FREE),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
class ThinkingOutputParser {
|
||||
|
||||
private val buffer = StringBuilder()
|
||||
|
||||
var isThinking: Boolean = false
|
||||
private set
|
||||
|
||||
var isFinished: Boolean = false
|
||||
private set
|
||||
|
||||
var thoughtProcess: String = ""
|
||||
private set
|
||||
|
||||
fun processChunk(chunk: String) {
|
||||
if (isFinished) {
|
||||
return
|
||||
}
|
||||
|
||||
buffer.append(chunk)
|
||||
|
||||
val thinkPattern = Pattern.compile("<think>(.*?)</think>", Pattern.DOTALL)
|
||||
val matcher = thinkPattern.matcher(buffer.toString())
|
||||
if (matcher.find()) {
|
||||
isFinished = true
|
||||
isThinking = false
|
||||
thoughtProcess = matcher.group(1).trim { it <= ' ' }
|
||||
} else if (buffer.isNotBlank() && "<think>".contains(buffer)) {
|
||||
thoughtProcess = ""
|
||||
isThinking = true
|
||||
} else if (buffer.toString().startsWith("<think>")) {
|
||||
thoughtProcess = buffer.toString().replaceFirst("<think>".toRegex(), "")
|
||||
isThinking = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -118,7 +118,7 @@ class UserMessagePanel(
|
|||
|
||||
private fun setupResponseBody() {
|
||||
addContent(
|
||||
ChatMessageResponseBody(project, false, true, false, false, parentDisposable)
|
||||
ChatMessageResponseBody(project, true, false, false, parentDisposable)
|
||||
.withResponse(message.prompt)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
package ee.carlrobert.codegpt.ui
|
||||
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.ui.JBColor
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.intellij.util.ui.components.BorderLayoutPanel
|
||||
import ee.carlrobert.codegpt.util.MarkdownUtil
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.event.ItemEvent
|
||||
import javax.swing.*
|
||||
|
||||
class ThoughtProcessPanel : JPanel(BorderLayout()) {
|
||||
|
||||
var finished: Boolean = false
|
||||
private set
|
||||
|
||||
private val responseBodyContent = UIUtil.createTextPane("", false)
|
||||
private val contentPanel = createContentPanel()
|
||||
private val toggleButton: JToggleButton = createToggleButton()
|
||||
|
||||
init {
|
||||
isOpaque = false
|
||||
|
||||
add(toggleButton, BorderLayout.NORTH)
|
||||
add(contentPanel, BorderLayout.CENTER)
|
||||
}
|
||||
|
||||
fun setFinished() {
|
||||
toggleButton.text = "Thought Process"
|
||||
toggleButton.isSelected = false
|
||||
finished = true
|
||||
|
||||
contentPanel.add(Box.createVerticalStrut(8))
|
||||
contentPanel.add(
|
||||
BorderLayoutPanel().withBorder(
|
||||
JBUI.Borders.compound(
|
||||
JBUI.Borders.customLine(JBColor.border(), 1, 0, 0, 0),
|
||||
JBUI.Borders.empty(8, 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun updateText(text: String) {
|
||||
responseBodyContent.text = MarkdownUtil.convertMdToHtml(text)
|
||||
}
|
||||
|
||||
private fun createContentPanel(): JPanel {
|
||||
val panel = JPanel().apply {
|
||||
isOpaque = false
|
||||
isVisible = true
|
||||
layout = BoxLayout(this, BoxLayout.Y_AXIS)
|
||||
border = JBUI.Borders.empty(0, 0)
|
||||
}
|
||||
|
||||
panel.add(responseBodyContent)
|
||||
panel.add(Box.createVerticalStrut(4))
|
||||
return panel
|
||||
}
|
||||
|
||||
private fun createToggleButton(): JToggleButton {
|
||||
return JToggleButton("Thinking...", AllIcons.General.ArrowUp)
|
||||
.apply {
|
||||
isFocusPainted = false
|
||||
isContentAreaFilled = false
|
||||
background = background
|
||||
selectedIcon = AllIcons.General.ArrowDown
|
||||
border = null
|
||||
isSelected = true
|
||||
horizontalAlignment = SwingConstants.LEFT
|
||||
horizontalTextPosition = SwingConstants.RIGHT
|
||||
iconTextGap = 4
|
||||
addItemListener { e: ItemEvent ->
|
||||
contentPanel.isVisible = e.stateChange == ItemEvent.SELECTED
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue