mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-22 11:38:28 +00:00
feat: Implement Ollama as a high-level service (#510)
* Initial implementation of Ollama as a service * Fix model selector in tool window * Enable image attachment * Rewrite OllamaSettingsForm in Kt * Create OllamaInlineCompletionModel and use it for building completion template * Add support for blocking code completion on models that we don't know support it * Allow disabling code completion settings * Disable code completion settings when an unsupported model is entered * Track FIM template in settings as a derived state * Update llm-client * Initial implementation of model combo box * Add Ollama icon and display models as list * Make OllamaSettingsState immutable & convert OllamaSettings to Kotlin * Add refresh models button * Distinguish between empty/needs refresh/loading * Avoid storing any model if the combo box is empty * Fix icon size * Back to mutable settings There were some bugs with immutable settings * Store available models in settings state * Expose available models in model dropdown * Add dark icon * Cleanups for CompletionRequestProvider * Fix checkstyle issues * refactor: migrate to SimplePersistentStateComponent * fix: add code completion stop tokens * fix: display only one item in the model popup action group * fix: add back multi model selection --------- Co-authored-by: Carl-Robert Linnupuu <carlrobertoh@gmail.com>
This commit is contained in:
parent
7b386686b0
commit
5fb6589dc6
20 changed files with 541 additions and 30 deletions
|
|
@ -26,8 +26,8 @@ import ee.carlrobert.codegpt.settings.service.ServiceType;
|
|||
import ee.carlrobert.codegpt.settings.service.anthropic.AnthropicSettings;
|
||||
import ee.carlrobert.codegpt.settings.service.custom.CustomServiceChatCompletionSettingsState;
|
||||
import ee.carlrobert.codegpt.settings.service.custom.CustomServiceSettings;
|
||||
import ee.carlrobert.codegpt.settings.service.custom.CustomServiceState;
|
||||
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.you.YouSettings;
|
||||
import ee.carlrobert.codegpt.telemetry.core.configuration.TelemetryConfiguration;
|
||||
|
|
@ -41,6 +41,8 @@ import ee.carlrobert.llm.client.anthropic.completion.ClaudeCompletionStandardMes
|
|||
import ee.carlrobert.llm.client.anthropic.completion.ClaudeMessageImageContent;
|
||||
import ee.carlrobert.llm.client.anthropic.completion.ClaudeMessageTextContent;
|
||||
import ee.carlrobert.llm.client.llama.completion.LlamaCompletionRequest;
|
||||
import ee.carlrobert.llm.client.ollama.completion.request.OllamaChatCompletionMessage;
|
||||
import ee.carlrobert.llm.client.ollama.completion.request.OllamaChatCompletionRequest;
|
||||
import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionModel;
|
||||
import ee.carlrobert.llm.client.openai.completion.request.OpenAIChatCompletionDetailedMessage;
|
||||
import ee.carlrobert.llm.client.openai.completion.request.OpenAIChatCompletionMessage;
|
||||
|
|
@ -56,6 +58,7 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
|
@ -140,7 +143,8 @@ public class CompletionRequestProvider {
|
|||
|
||||
public static Request buildCustomOpenAILookupCompletionRequest(String context) {
|
||||
return buildCustomOpenAIChatCompletionRequest(
|
||||
ApplicationManager.getApplication().getService(CustomServiceState.class)
|
||||
ApplicationManager.getApplication().getService(CustomServiceSettings.class)
|
||||
.getState()
|
||||
.getChatCompletionSettings(),
|
||||
List.of(
|
||||
new OpenAIChatCompletionStandardMessage(
|
||||
|
|
@ -210,7 +214,7 @@ public class CompletionRequestProvider {
|
|||
@Nullable String model,
|
||||
CallParameters callParameters) {
|
||||
var configuration = ConfigurationSettings.getCurrentState();
|
||||
return new OpenAIChatCompletionRequest.Builder(buildMessages(model, callParameters))
|
||||
return new OpenAIChatCompletionRequest.Builder(buildOpenAIMessages(model, callParameters))
|
||||
.setModel(model)
|
||||
.setMaxTokens(configuration.getMaxTokens())
|
||||
.setStream(true)
|
||||
|
|
@ -222,7 +226,7 @@ public class CompletionRequestProvider {
|
|||
CallParameters callParameters) {
|
||||
return buildCustomOpenAIChatCompletionRequest(
|
||||
settings,
|
||||
buildMessages(callParameters),
|
||||
buildOpenAIMessages(callParameters),
|
||||
true);
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +311,68 @@ public class CompletionRequestProvider {
|
|||
return request;
|
||||
}
|
||||
|
||||
private List<OpenAIChatCompletionMessage> buildMessages(CallParameters callParameters) {
|
||||
public OllamaChatCompletionRequest buildOllamaChatCompletionRequest(
|
||||
CallParameters callParameters
|
||||
) {
|
||||
var settings = ApplicationManager.getApplication().getService(OllamaSettings.class).getState();
|
||||
return new OllamaChatCompletionRequest
|
||||
.Builder(settings.getModel(), buildOllamaMessages(callParameters))
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<OllamaChatCompletionMessage> buildOllamaMessages(CallParameters callParameters) {
|
||||
var message = callParameters.getMessage();
|
||||
var messages = new ArrayList<OllamaChatCompletionMessage>();
|
||||
if (callParameters.getConversationType() == ConversationType.DEFAULT) {
|
||||
String systemPrompt = ConfigurationSettings.getCurrentState().getSystemPrompt();
|
||||
messages.add(new OllamaChatCompletionMessage("system", systemPrompt, null));
|
||||
}
|
||||
if (callParameters.getConversationType() == ConversationType.FIX_COMPILE_ERRORS) {
|
||||
messages.add(
|
||||
new OllamaChatCompletionMessage("system", FIX_COMPILE_ERRORS_SYSTEM_PROMPT, null)
|
||||
);
|
||||
}
|
||||
|
||||
for (var prevMessage : conversation.getMessages()) {
|
||||
if (callParameters.isRetry() && prevMessage.getId().equals(message.getId())) {
|
||||
break;
|
||||
}
|
||||
var prevMessageImageFilePath = prevMessage.getImageFilePath();
|
||||
if (prevMessageImageFilePath != null && !prevMessageImageFilePath.isEmpty()) {
|
||||
try {
|
||||
var imageFilePath = Path.of(prevMessageImageFilePath);
|
||||
var imageBytes = Files.readAllBytes(imageFilePath);
|
||||
var imageBase64 = Base64.getEncoder().encodeToString(imageBytes);
|
||||
messages.add(
|
||||
new OllamaChatCompletionMessage(
|
||||
"user", prevMessage.getPrompt(), List.of(imageBase64)
|
||||
)
|
||||
);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
messages.add(
|
||||
new OllamaChatCompletionMessage("user", prevMessage.getPrompt(), null)
|
||||
);
|
||||
}
|
||||
messages.add(
|
||||
new OllamaChatCompletionMessage("assistant", prevMessage.getResponse(), null)
|
||||
);
|
||||
}
|
||||
|
||||
if (callParameters.getImageMediaType() != null && callParameters.getImageData().length > 0) {
|
||||
var imageBase64 = Base64.getEncoder().encodeToString(callParameters.getImageData());
|
||||
messages.add(
|
||||
new OllamaChatCompletionMessage("user", message.getPrompt(), List.of(imageBase64))
|
||||
);
|
||||
} else {
|
||||
messages.add(new OllamaChatCompletionMessage("user", message.getPrompt(), null));
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
private List<OpenAIChatCompletionMessage> buildOpenAIMessages(CallParameters callParameters) {
|
||||
var message = callParameters.getMessage();
|
||||
var messages = new ArrayList<OpenAIChatCompletionMessage>();
|
||||
if (callParameters.getConversationType() == ConversationType.DEFAULT) {
|
||||
|
|
@ -339,7 +404,9 @@ public class CompletionRequestProvider {
|
|||
} else {
|
||||
messages.add(new OpenAIChatCompletionStandardMessage("user", prevMessage.getPrompt()));
|
||||
}
|
||||
messages.add(new OpenAIChatCompletionStandardMessage("assistant", prevMessage.getResponse()));
|
||||
messages.add(
|
||||
new OpenAIChatCompletionStandardMessage("assistant", prevMessage.getResponse())
|
||||
);
|
||||
}
|
||||
|
||||
if (callParameters.getImageMediaType() != null && callParameters.getImageData().length > 0) {
|
||||
|
|
@ -355,10 +422,10 @@ public class CompletionRequestProvider {
|
|||
return messages;
|
||||
}
|
||||
|
||||
private List<OpenAIChatCompletionMessage> buildMessages(
|
||||
private List<OpenAIChatCompletionMessage> buildOpenAIMessages(
|
||||
@Nullable String model,
|
||||
CallParameters callParameters) {
|
||||
var messages = buildMessages(callParameters);
|
||||
var messages = buildOpenAIMessages(callParameters);
|
||||
|
||||
if (model == null
|
||||
|| GeneralSettings.getCurrentState().getSelectedService() == ServiceType.YOU) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue