diff --git a/plugin/src/de/hetzge/eclipse/aicoder/llm/LlmPromptTemplates.java b/plugin/src/de/hetzge/eclipse/aicoder/llm/LlmPromptTemplates.java index 8268094..9d0575b 100644 --- a/plugin/src/de/hetzge/eclipse/aicoder/llm/LlmPromptTemplates.java +++ b/plugin/src/de/hetzge/eclipse/aicoder/llm/LlmPromptTemplates.java @@ -21,6 +21,118 @@ public static String changeCodeSystemPrompt() { """.trim(); } + public static String pseudoFimCodeSystemPrompt() { + return """ + You are an expert code completion AI. + Complete the code. + - The user will provide a code snippet formatted as a "Fill in the Middle" (FIM) request with <|fim_prefix|>, <|fim_suffix|>, and <|fim_middle|> tags. + - You must strictly complete the code, starting immediately after the <|fim_middle|> tag, and return **ONLY** the generated completion code, without any surrounding explanation or text. + - Do not include the prefix or suffix in your response. + - Do not repeat any of the provided context in the response. + - Partial code snippets are expected. + - Apply the following examples returning multiple lines unless instructed to return only a single line assuming the user will complete subsequent lines. + - Provide the completion that fills in the missing code. + + :::Example prompts and responses::: + + Example 1: + ``` + <|fim_prefix|># Current edit location: [path]; + + public class Main { + + public static void main(String[] args) { + // TODO: add a for loop count from 1 to 10 + for (<|fim_suffix|> + } + } + <|fim_middle|> + ``` + Correct response: + ``` + int i = 1; i <= 10; i++) { + System.out.println(i); + } + ``` + + Example 2: + ``` + <|fim_prefix|># Current edit location: [path]; + + public class Main { + + public static void main(String[] args) { + // TODO: add a for loop count from 1 to 10 + for(<|fim_suffix|>) + } + } + <|fim_middle|> + ``` + Correct response: + ```int i = 1; i <= 10; i++``` + + Example 3: "<|fim_prefix|># Current edit location: [path]; + ``` + public class Main { + + public static void main(String[] args) { + int j = 100; + while(j<|fim_suffix|> + } + } + <|fim_middle|> + ``` + Correct response: + ``` + > 0) { + System.out.println(j); + j--; + } + ``` + Example 4: + ``` + <|fim_prefix|># Current edit location: [path]; + + public class Main { + + public static void main(String[] args) { + int j = 100; + while(j<|fim_suffix|>) + } + } + <|fim_middle|> + ``` + Correct response: + is: + ``` > 0``` + + Example 5: + ``` + <|fim_prefix|># Current edit location: [path]; + + public class Main { + + public static void main(String[] args) { + String title = "A FIM example."; + System.out + } + } + <|fim_middle|> + ``` + Correct response: + ```.println(title);``` + + ## Additional information ## + - Use Java 21 syntax + - Use the correct variables based on the context + - If a comment precedes the line to you be completed, implement it + - Focus on short, high confidence completions + - Do not generate extraneous code that does not logically fill in the completion + - When the completion is combined with the context code, it should be logically and syntactically correct and compliable + - Pay attention to opening and closing characters such as braces and parentheses + """.trim(); + } + public static String generateCodeSystemPrompt() { return """ You are a software developer assistant. diff --git a/plugin/src/de/hetzge/eclipse/aicoder/llm/LlmUtils.java b/plugin/src/de/hetzge/eclipse/aicoder/llm/LlmUtils.java index 8ac8260..eee9960 100644 --- a/plugin/src/de/hetzge/eclipse/aicoder/llm/LlmUtils.java +++ b/plugin/src/de/hetzge/eclipse/aicoder/llm/LlmUtils.java @@ -54,153 +54,204 @@ private static LlmResponse execute(LlmOption llmModelOption, String systemPrompt } private static LlmResponse executeOllama(LlmOption llmModelOption, String systemPrompt, String prompt, String suffix) throws IOException { - final boolean isFillInTheMiddle = suffix != null; - final String urlString = AiCoderPreferences.getOllamaBaseUrl(); - final boolean multilineEnabled = AiCoderPreferences.isMultilineEnabled(); - final Json json = Json.object() - .set("model", llmModelOption.modelKey()) - .set("prompt", prompt) - .set("stream", false) - .set("options", Json.object() - .set("temperature", 0)); - if (systemPrompt != null) { - json.set("system", systemPrompt); - } - if (isFillInTheMiddle) { - json.set("suffix", suffix); - json.at("options") - .set("num_predict", AiCoderPreferences.getMaxTokens()) - .set("stop", createStop(multilineEnabled)); - } - final URL url = URI.create(urlString).resolve("/api/generate").toURL(); - final long beforeTimestamp = System.currentTimeMillis(); - final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestProperty("Accept", "application/json"); - connection.setDoOutput(true); - HttpUtils.writeRequestBody(connection, json); - final int responseCode = connection.getResponseCode(); - if (responseCode == HttpURLConnection.HTTP_OK) { - final String responseBody = HttpUtils.readResponseBody(connection); - final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); - final Json responseJson = Json.read(responseBody); - final String content = responseJson.at("response").asString(); - final int inputTokens = responseJson.at("prompt_eval_count").asInteger(); - final int outputTokens = responseJson.at("eval_count").asInteger(); - return new LlmResponse(llmModelOption, content, responseBody, inputTokens, outputTokens, duration, false); - } else { - AiCoderActivator.log().log(new Status(IStatus.WARNING, AiCoderActivator.PLUGIN_ID, String.format("Error: %s (%s)", connection.getResponseMessage(), responseCode))); - final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); - final String responseBody = HttpUtils.readErrorResponseBody(connection); - return new LlmResponse(llmModelOption, "", responseBody, 0, 0, duration, true); - } + final boolean isFillInTheMiddle = suffix != null; + final boolean isPseudoFim = isFillInTheMiddle && AiCoderPreferences.isEnablePseduoFim(); + + final String urlString = AiCoderPreferences.getOllamaBaseUrl(); + final boolean multilineEnabled = AiCoderPreferences.isMultilineEnabled(); + String currentSystemPrompt = systemPrompt; + String currentPrompt = prompt; + if (isPseudoFim) { + String fimPayload = JinjaUtils.applyTemplate(AiCoderPreferences.getOpenAiFimTemplate(), Map.ofEntries( + Map.entry("prefix", prompt), + Map.entry("suffix", suffix))); + currentSystemPrompt = getPseduoFIMSystemPrompt(AiCoderPreferences.getPseudoFimSystemPrompt(), multilineEnabled); + currentPrompt = fimPayload; + } + final Json json = Json.object() + .set("model", llmModelOption.modelKey()) + .set("prompt", currentPrompt) + .set("stream", false) + .set("options", Json.object() + .set("temperature", 0)); + if (currentSystemPrompt != null) { + json.set("system", currentSystemPrompt); + } + if (isFillInTheMiddle) { + json.at("options").set("num_predict", AiCoderPreferences.getMaxTokens()); + if (!isPseudoFim) { + json.set("suffix", suffix); + json.at("options").set("stop", createStop(multilineEnabled)); + } + } + + final URL url = URI.create(urlString).resolve("/api/generate").toURL(); + final long beforeTimestamp = System.currentTimeMillis(); + final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("Accept", "application/json"); + connection.setDoOutput(true); + HttpUtils.writeRequestBody(connection, json); + final int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + final String responseBody = HttpUtils.readResponseBody(connection); + final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); + final Json responseJson = Json.read(responseBody); + String content = responseJson.at("response").asString(); + if (isPseudoFim) + content = content.trim(); + final int inputTokens = responseJson.at("prompt_eval_count").asInteger(); + final int outputTokens = responseJson.at("eval_count").asInteger(); + return new LlmResponse(llmModelOption, content, responseBody, inputTokens, outputTokens, duration, false); + } else { + AiCoderActivator.log().log(new Status(IStatus.WARNING, AiCoderActivator.PLUGIN_ID, String.format("Error: %s (%s)", connection.getResponseMessage(), responseCode))); + final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); + final String responseBody = HttpUtils.readErrorResponseBody(connection); + return new LlmResponse(llmModelOption, "", responseBody, 0, 0, duration, true); + } } private static LlmResponse executeMistral(LlmOption llmModelOption, String systemPrompt, String prompt, String suffix) throws IOException { - final boolean isFillInTheMiddle = suffix != null; - final String urlString = "https://codestral.mistral.ai"; - final String codestralApiKey = AiCoderPreferences.getCodestralApiKey(); - final boolean multilineEnabled = AiCoderPreferences.isMultilineEnabled(); - final Json json = Json.object() - .set("model", llmModelOption.modelKey()) - .set("temperature", 0); - if (isFillInTheMiddle) { - json.set("prompt", prompt) - .set("suffix", suffix) - .set("max_tokens", AiCoderPreferences.getMaxTokens()) - .set("stop", createStop(multilineEnabled)); - } else { - final Json messagesJson = Json.array(); - if (systemPrompt != null) { - messagesJson.add(Json.object() - .set("role", "system") - .set("content", systemPrompt)); - } - messagesJson.add(Json.object() - .set("role", "user") - .set("content", prompt)); - json.set("messages", messagesJson); - } - final String path = isFillInTheMiddle ? "/v1/fim/completions" : "/v1/chat/completions"; - final URL url = URI.create(urlString).resolve(path).toURL(); - final long beforeTimestamp = System.currentTimeMillis(); - final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestProperty("Accept", "application/json"); - connection.setRequestProperty("Authorization", "Bearer " + codestralApiKey); - connection.setDoOutput(true); - HttpUtils.writeRequestBody(connection, json); - final int responseCode = connection.getResponseCode(); - if (responseCode == HttpURLConnection.HTTP_OK) { - final String responseBody = HttpUtils.readResponseBody(connection); - final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); - final Json responseJson = Json.read(responseBody); - final String content = responseJson.at("choices").at(0).at("message").at("content").asString(); - final int inputTokens = responseJson.at("usage").at("prompt_tokens").asInteger(); - final int outputTokens = responseJson.at("usage").at("completion_tokens").asInteger(); - return new LlmResponse(llmModelOption, content, responseBody, inputTokens, outputTokens, duration, false); - } else { - AiCoderActivator.log().log(new Status(IStatus.WARNING, AiCoderActivator.PLUGIN_ID, String.format("Error: %s (%s)", connection.getResponseMessage(), responseCode))); - final String responseBody = HttpUtils.readErrorResponseBody(connection); - final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); - return new LlmResponse(llmModelOption, "", responseBody, 0, 0, duration, true); - } + final boolean isFillInTheMiddle = suffix != null; + final boolean isPseudoFim = isFillInTheMiddle && AiCoderPreferences.isEnablePseduoFim(); + final String urlString = "https://codestral.mistral.ai"; + final String codestralApiKey = AiCoderPreferences.getCodestralApiKey(); + final boolean multilineEnabled = AiCoderPreferences.isMultilineEnabled(); + final Json json = Json.object() + .set("model", llmModelOption.modelKey()) + .set("temperature", 0); + String currentSystemPrompt = systemPrompt; + String currentPrompt = prompt; + if (isFillInTheMiddle && !isPseudoFim) { + json.set("prompt", currentPrompt) + .set("suffix", suffix) + .set("max_tokens", AiCoderPreferences.getMaxTokens()) + .set("stop", createStop(multilineEnabled)); + } else { + final Json messagesJson = Json.array(); + if (isPseudoFim) { + currentPrompt = JinjaUtils.applyTemplate(AiCoderPreferences.getOpenAiFimTemplate(), Map.ofEntries( + Map.entry("prefix", prompt), + Map.entry("suffix", suffix))); + currentSystemPrompt = getPseduoFIMSystemPrompt(AiCoderPreferences.getPseudoFimSystemPrompt(), multilineEnabled); // APPLY MULTILINE INSTRUCTION + json.set("max_tokens", AiCoderPreferences.getMaxTokens()); + } + if (currentSystemPrompt != null) { + messagesJson.add(Json.object() + .set("role", "system") + .set("content", currentSystemPrompt)); + } + messagesJson.add(Json.object() + .set("role", "user") + .set("content", currentPrompt)); + + json.set("messages", messagesJson); + } + final String path = isFillInTheMiddle && !isPseudoFim ? "/v1/fim/completions" : "/v1/chat/completions"; + final URL url = URI.create(urlString).resolve(path).toURL(); + final long beforeTimestamp = System.currentTimeMillis(); + final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("Accept", "application/json"); + connection.setRequestProperty("Authorization", "Bearer " + codestralApiKey); + connection.setDoOutput(true); + HttpUtils.writeRequestBody(connection, json); + + final int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + final String responseBody = HttpUtils.readResponseBody(connection); + final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); + final Json responseJson = Json.read(responseBody); + String content; + content = responseJson.at("choices").at(0).at("message").at("content").asString(); + if (isPseudoFim) + content = content.trim(); + final int inputTokens = responseJson.at("usage").at("prompt_tokens").asInteger(); + final int outputTokens = responseJson.at("usage").at("completion_tokens").asInteger(); + return new LlmResponse(llmModelOption, content, responseBody, inputTokens, outputTokens, duration, false); + } else { + AiCoderActivator.log().log(new Status(IStatus.WARNING, AiCoderActivator.PLUGIN_ID, String.format("Error: %s (%s)", connection.getResponseMessage(), responseCode))); + final String responseBody = HttpUtils.readErrorResponseBody(connection); + final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); + return new LlmResponse(llmModelOption, "", responseBody, 0, 0, duration, true); + } } private static LlmResponse executeOpenAi(LlmOption llmModelOption, String systemPrompt, String prompt, String suffix) throws IOException { - final boolean isFillInTheMiddle = suffix != null; - final String urlString = AiCoderPreferences.getOpenAiBaseUrl(); - final String openAiApiKey = AiCoderPreferences.getOpenAiApiKey(); - final Json json = Json.object() - .set("model", llmModelOption.modelKey()) - .set("temperature", 0); - if (!isFillInTheMiddle) { - final Json messagesJson = Json.array(); - if (systemPrompt != null) { - messagesJson.add(Json.object() - .set("role", "system") - .set("content", systemPrompt)); - } - messagesJson.add(Json.object() - .set("role", "user") - .set("content", prompt)); - json.set("messages", messagesJson); - } else { - final String fimPrompt = JinjaUtils.applyTemplate(AiCoderPreferences.getOpenAiFimTemplate(), Map.ofEntries( - Map.entry("prefix", prompt), - Map.entry("suffix", suffix))); - json.set("prompt", fimPrompt) - .set("max_tokens", AiCoderPreferences.getMaxTokens()); - } - - final URL url = URI.create(urlString + "/").resolve(isFillInTheMiddle ? "./v1/completions" : "./v1/chat/completions").toURL(); - final long beforeTimestamp = System.currentTimeMillis(); - final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestProperty("Accept", "application/json"); - connection.setRequestProperty("Authorization", "Bearer " + openAiApiKey); - connection.setDoOutput(true); - HttpUtils.writeRequestBody(connection, json); - final int responseCode = connection.getResponseCode(); - if (responseCode == HttpURLConnection.HTTP_OK) { - final String responseBody = HttpUtils.readResponseBody(connection); - final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); - final Json responseJson = Json.read(responseBody); - final String content = isFillInTheMiddle - ? responseJson.at("choices").at(0).at("text").asString() - : responseJson.at("choices").at(0).at("message").at("content").asString(); - final int inputTokens = responseJson.at("usage").at("prompt_tokens").asInteger(); - final int outputTokens = responseJson.at("usage").at("completion_tokens").asInteger(); - return new LlmResponse(llmModelOption, content, responseBody, inputTokens, outputTokens, duration, false); - } else { - AiCoderActivator.log().log(new Status(IStatus.WARNING, AiCoderActivator.PLUGIN_ID, String.format("Error: %s (%s)", connection.getResponseMessage(), responseCode))); - final String responseBody = HttpUtils.readErrorResponseBody(connection); - final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); - return new LlmResponse(llmModelOption, "", responseBody, 0, 0, duration, true); - } + final boolean isFillInTheMiddle = suffix != null; + final boolean isPseudoFim = isFillInTheMiddle && AiCoderPreferences.isEnablePseduoFim(); + final String urlString = AiCoderPreferences.getOpenAiBaseUrl(); + final String openAiApiKey = AiCoderPreferences.getOpenAiApiKey(); + final boolean multilineEnabled = AiCoderPreferences.isMultilineEnabled(); // Fetch multilineEnabled here + final Json json = Json.object() + .set("model", llmModelOption.modelKey()) + .set("temperature", 0); + if (!isFillInTheMiddle || isPseudoFim) { + final Json messagesJson = Json.array(); + String currentSystemPrompt = systemPrompt; + if (isPseudoFim) { + final String fimPrompt = JinjaUtils.applyTemplate(AiCoderPreferences.getOpenAiFimTemplate(), Map.ofEntries( + Map.entry("prefix", prompt), + Map.entry("suffix", suffix))); + currentSystemPrompt = getPseduoFIMSystemPrompt(AiCoderPreferences.getPseudoFimSystemPrompt(), multilineEnabled); // Use the new function for system prompt + prompt = fimPrompt; + json.set("max_tokens", AiCoderPreferences.getMaxTokens()); + } + if (currentSystemPrompt != null) { + messagesJson.add(Json.object() + .set("role", "system") + .set("content", currentSystemPrompt)); + } + messagesJson.add(Json.object() + .set("role", "user") + .set("content", prompt)); + json.set("messages", messagesJson); + } else { + final String fimPrompt = JinjaUtils.applyTemplate(AiCoderPreferences.getOpenAiFimTemplate(), Map.ofEntries( + Map.entry("prefix", prompt), + Map.entry("suffix", suffix))); + json.set("prompt", fimPrompt) + .set("max_tokens", AiCoderPreferences.getMaxTokens()); + } + + final URL url = URI.create(urlString + "/").resolve(isFillInTheMiddle && !isPseudoFim ? "./v1/completions" : "./v1/chat/completions").toURL(); + final long beforeTimestamp = System.currentTimeMillis(); + final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("Accept", "application/json"); + connection.setRequestProperty("Authorization", "Bearer " + openAiApiKey); + connection.setDoOutput(true); + HttpUtils.writeRequestBody(connection, json); + final int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + final String responseBody = HttpUtils.readResponseBody(connection); + final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); + final Json responseJson = Json.read(responseBody); + String content; + if (isFillInTheMiddle && !isPseudoFim) { + content = responseJson.at("choices").at(0).at("text").asString(); + } else { + content = responseJson.at("choices").at(0).at("message").at("content").asString(); + if (isPseudoFim) + content = content.trim(); + } + final int inputTokens = responseJson.at("usage").at("prompt_tokens").asInteger(); + final int outputTokens = responseJson.at("usage").at("completion_tokens").asInteger(); + return new LlmResponse(llmModelOption, content, responseBody, inputTokens, outputTokens, duration, false); + } else { + AiCoderActivator.log().log(new Status(IStatus.WARNING, AiCoderActivator.PLUGIN_ID, String.format("Error: %s (%s)", connection.getResponseMessage(), responseCode))); + final String responseBody = HttpUtils.readErrorResponseBody(connection); + final Duration duration = Duration.ofMillis(System.currentTimeMillis() - beforeTimestamp); + return new LlmResponse(llmModelOption, "", responseBody, 0, 0, duration, true); + } + } + + private static String getPseduoFIMSystemPrompt(String fimSystemPrompt, boolean multilineEnabled) { + return fimSystemPrompt + (multilineEnabled?"":"\\nOnly generate a single line of code."); } private static Json createStop(final boolean multilineEnabled) { diff --git a/plugin/src/de/hetzge/eclipse/aicoder/preferences/AiCoderPreferences.java b/plugin/src/de/hetzge/eclipse/aicoder/preferences/AiCoderPreferences.java index fa3c5f3..55323cb 100644 --- a/plugin/src/de/hetzge/eclipse/aicoder/preferences/AiCoderPreferences.java +++ b/plugin/src/de/hetzge/eclipse/aicoder/preferences/AiCoderPreferences.java @@ -41,6 +41,8 @@ public final class AiCoderPreferences extends AbstractPreferenceInitializer { public static final String CHANGE_CODE_SYSTEM_PROMPT_KEY = "de.hetzge.eclipse.aicoder.change_code_system_prompt"; public static final String GENERATE_CODE_SYSTEM_PROMPT_KEY = "de.hetzge.eclipse.aicoder.generate_code_system_prompt"; public static final String OPENAI_FIM_TEMPLATE_KEY = "de.hetzge.eclipse.aicoder.openai_fim_template"; + public static final String ENABLE_PSEUDO_FIM_KEY = "de.hetzge.eclipse.aicoder.enable_pseduo_fim"; + public static final String PSEUDO_FIM_SYSTEM_PROMPT_KEY = "de.hetzge.eclipse.aicoder.pseudo_fim_system_prompt"; @Override public void initializeDefaultPreferences() { @@ -72,10 +74,13 @@ public void initializeDefaultPreferences() { store.setDefault(CHANGE_CODE_SYSTEM_PROMPT_KEY, LlmPromptTemplates.changeCodeSystemPrompt()); store.setDefault(GENERATE_CODE_SYSTEM_PROMPT_KEY, LlmPromptTemplates.generateCodeSystemPrompt()); store.setDefault(OPENAI_FIM_TEMPLATE_KEY, "<|fim_prefix|>{{prefix}}<|fim_suffix|>{{suffix}}<|fim_middle|>"); + store.setDefault(ENABLE_PSEUDO_FIM_KEY, false); + store.setDefault(PSEUDO_FIM_SYSTEM_PROMPT_KEY, LlmPromptTemplates.pseudoFimCodeSystemPrompt()); } public static String getCodestralApiKey() { return getStore().getString(CODESTRAL_API_KEY_KEY); + } public static String getOllamaBaseUrl() { @@ -202,9 +207,16 @@ public static String getChangeCodeSystemPrompt() { public static String getGenerateCodeSystemPrompt() { return getStore().getString(GENERATE_CODE_SYSTEM_PROMPT_KEY); } - + public static String getOpenAiFimTemplate() { return getStore().getString(OPENAI_FIM_TEMPLATE_KEY); } - + + public static boolean isEnablePseduoFim() { + return getStore().getBoolean(ENABLE_PSEUDO_FIM_KEY); + } + + public static String getPseudoFimSystemPrompt() { + return getStore().getString(PSEUDO_FIM_SYSTEM_PROMPT_KEY); + } } \ No newline at end of file diff --git a/plugin/src/de/hetzge/eclipse/aicoder/preferences/LlmPreferencePage.java b/plugin/src/de/hetzge/eclipse/aicoder/preferences/LlmPreferencePage.java index 158a326..bf9af57 100644 --- a/plugin/src/de/hetzge/eclipse/aicoder/preferences/LlmPreferencePage.java +++ b/plugin/src/de/hetzge/eclipse/aicoder/preferences/LlmPreferencePage.java @@ -5,6 +5,7 @@ import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.ComboFieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.StringFieldEditor; @@ -71,6 +72,11 @@ protected void createFieldEditors() { fillInMiddleModelEditor.setStringValue(llmOption.modelKey()); } })); + // Pseudo FIM + addField(new BooleanFieldEditor( + AiCoderPreferences.ENABLE_PSEUDO_FIM_KEY, + "Enable Pseudo FIM", + fillInMiddleModelGroup)); final Group quickFixModelGroup = new Group(getFieldEditorParent(), SWT.NONE); quickFixModelGroup.setText("Quick fix LLM"); diff --git a/plugin/src/de/hetzge/eclipse/aicoder/preferences/PromptsPreferencePage.java b/plugin/src/de/hetzge/eclipse/aicoder/preferences/PromptsPreferencePage.java index 997ecb0..e988ecf 100644 --- a/plugin/src/de/hetzge/eclipse/aicoder/preferences/PromptsPreferencePage.java +++ b/plugin/src/de/hetzge/eclipse/aicoder/preferences/PromptsPreferencePage.java @@ -24,5 +24,6 @@ protected void createFieldEditors() { addField(new StringFieldEditor(AiCoderPreferences.QUICK_FIX_PROMPT_KEY, "Quick fix prompt", StringFieldEditor.UNLIMITED, 7, StringFieldEditor.VALIDATE_ON_KEY_STROKE, getFieldEditorParent())); addField(new StringFieldEditor(AiCoderPreferences.CHANGE_CODE_SYSTEM_PROMPT_KEY, "Change code system prompt", StringFieldEditor.UNLIMITED, 7, StringFieldEditor.VALIDATE_ON_KEY_STROKE, getFieldEditorParent())); addField(new StringFieldEditor(AiCoderPreferences.GENERATE_CODE_SYSTEM_PROMPT_KEY, "Generate code system prompt", StringFieldEditor.UNLIMITED, 7, StringFieldEditor.VALIDATE_ON_KEY_STROKE, getFieldEditorParent())); + addField(new StringFieldEditor(AiCoderPreferences.PSEUDO_FIM_SYSTEM_PROMPT_KEY, "Pseduo FIM system prompt", StringFieldEditor.UNLIMITED, 7, StringFieldEditor.VALIDATE_ON_KEY_STROKE, getFieldEditorParent())); } }