Skip to content

Commit c8181a6

Browse files
authored
feat: add input field for llama server build parameters and improve error handling (#481)
1 parent 67dc425 commit c8181a6

File tree

9 files changed

+138
-49
lines changed

9 files changed

+138
-49
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ tasks {
149149
runIde {
150150
enabled = true
151151
environment("ENVIRONMENT", "LOCAL")
152+
autoReloadPlugins.set(false) // is triggered when building llama server
152153
}
153154

154155
test {

src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerAgent.java

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@
1414
import com.intellij.openapi.application.ApplicationManager;
1515
import com.intellij.openapi.components.Service;
1616
import com.intellij.openapi.diagnostic.Logger;
17+
import com.intellij.openapi.ui.MessageType;
1718
import com.intellij.openapi.util.Key;
1819
import ee.carlrobert.codegpt.CodeGPTBundle;
1920
import ee.carlrobert.codegpt.CodeGPTPlugin;
2021
import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings;
2122
import ee.carlrobert.codegpt.settings.service.llama.form.ServerProgressPanel;
23+
import ee.carlrobert.codegpt.ui.OverlayUtil;
2224
import java.nio.charset.StandardCharsets;
2325
import java.util.List;
2426
import java.util.concurrent.CopyOnWriteArrayList;
27+
import java.util.function.Consumer;
2528
import org.jetbrains.annotations.NotNull;
2629
import org.jetbrains.annotations.Nullable;
2730

@@ -32,65 +35,94 @@ public final class LlamaServerAgent implements Disposable {
3235

3336
private @Nullable OSProcessHandler makeProcessHandler;
3437
private @Nullable OSProcessHandler startServerProcessHandler;
38+
private ServerProgressPanel activeServerProgressPanel;
39+
private boolean stoppedByUser;
3540

3641
public void startAgent(
3742
LlamaServerStartupParams params,
3843
ServerProgressPanel serverProgressPanel,
3944
Runnable onSuccess,
40-
Runnable onServerTerminated) {
45+
Consumer<ServerProgressPanel> onServerTerminated) {
46+
this.activeServerProgressPanel = serverProgressPanel;
4147
ApplicationManager.getApplication().invokeLater(() -> {
4248
try {
43-
serverProgressPanel.updateText(
49+
stoppedByUser = false;
50+
serverProgressPanel.displayText(
4451
CodeGPTBundle.get("llamaServerAgent.buildingProject.description"));
45-
makeProcessHandler = new OSProcessHandler(getMakeCommandLinde());
52+
makeProcessHandler = new OSProcessHandler(
53+
getMakeCommandLine(params.additionalBuildParameters()));
4654
makeProcessHandler.addProcessListener(
47-
getMakeProcessListener(params, serverProgressPanel, onSuccess, onServerTerminated));
55+
getMakeProcessListener(params, onSuccess, onServerTerminated));
4856
makeProcessHandler.startNotify();
4957
} catch (ExecutionException e) {
50-
throw new RuntimeException(e);
58+
showServerError(e.getMessage(), onServerTerminated);
5159
}
5260
});
5361
}
5462

5563
public void stopAgent() {
64+
stoppedByUser = true;
65+
if (makeProcessHandler != null) {
66+
makeProcessHandler.destroyProcess();
67+
}
5668
if (startServerProcessHandler != null) {
5769
startServerProcessHandler.destroyProcess();
5870
}
5971
}
6072

6173
public boolean isServerRunning() {
62-
return startServerProcessHandler != null
74+
return (makeProcessHandler != null
75+
&& makeProcessHandler.isStartNotified()
76+
&& !makeProcessHandler.isProcessTerminated())
77+
|| (startServerProcessHandler != null
6378
&& startServerProcessHandler.isStartNotified()
64-
&& !startServerProcessHandler.isProcessTerminated();
79+
&& !startServerProcessHandler.isProcessTerminated());
6580
}
6681

6782
private ProcessListener getMakeProcessListener(
6883
LlamaServerStartupParams params,
69-
ServerProgressPanel serverProgressPanel,
7084
Runnable onSuccess,
71-
Runnable onServerTerminated) {
85+
Consumer<ServerProgressPanel> onServerTerminated) {
7286
LOG.info("Building llama project");
7387

7488
return new ProcessAdapter() {
89+
90+
private final List<String> errorLines = new CopyOnWriteArrayList<>();
91+
7592
@Override
7693
public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) {
94+
if (ProcessOutputType.isStderr(outputType)) {
95+
errorLines.add(event.getText());
96+
return;
97+
}
7798
LOG.info(event.getText());
7899
}
79100

80101
@Override
81102
public void processTerminated(@NotNull ProcessEvent event) {
103+
int exitCode = event.getExitCode();
104+
LOG.info(format("Server build exited with code %d", exitCode));
105+
if (stoppedByUser) {
106+
onServerTerminated.accept(activeServerProgressPanel);
107+
return;
108+
}
109+
if (exitCode != 0) {
110+
showServerError(String.join(",", errorLines), onServerTerminated);
111+
return;
112+
}
113+
82114
try {
83115
LOG.info("Booting up llama server");
84116

85-
serverProgressPanel.updateText(
117+
activeServerProgressPanel.displayText(
86118
CodeGPTBundle.get("llamaServerAgent.serverBootup.description"));
87119
startServerProcessHandler = new OSProcessHandler.Silent(getServerCommandLine(params));
88120
startServerProcessHandler.addProcessListener(
89-
getProcessListener(params.port(), onSuccess, onServerTerminated));
121+
getProcessListener(params.port(), onSuccess,
122+
onServerTerminated));
90123
startServerProcessHandler.startNotify();
91124
} catch (ExecutionException ex) {
92-
LOG.error("Unable to start llama server", ex);
93-
throw new RuntimeException(ex);
125+
showServerError(ex.getMessage(), onServerTerminated);
94126
}
95127
}
96128
};
@@ -99,27 +131,25 @@ public void processTerminated(@NotNull ProcessEvent event) {
99131
private ProcessListener getProcessListener(
100132
int port,
101133
Runnable onSuccess,
102-
Runnable onServerTerminated) {
134+
Consumer<ServerProgressPanel> onServerTerminated) {
103135
return new ProcessAdapter() {
104136
private final ObjectMapper objectMapper = new ObjectMapper();
105137
private final List<String> errorLines = new CopyOnWriteArrayList<>();
106138

107139
@Override
108140
public void processTerminated(@NotNull ProcessEvent event) {
109-
if (errorLines.isEmpty()) {
110-
LOG.info(format("Server terminated with code %d", event.getExitCode()));
141+
LOG.info(format("Server terminated with code %d", event.getExitCode()));
142+
if (stoppedByUser) {
143+
onServerTerminated.accept(activeServerProgressPanel);
111144
} else {
112-
LOG.info(String.join("", errorLines));
145+
showServerError(String.join(",", errorLines), onServerTerminated);
113146
}
114-
115-
onServerTerminated.run();
116147
}
117148

118149
@Override
119150
public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) {
120151
if (ProcessOutputType.isStderr(outputType)) {
121152
errorLines.add(event.getText());
122-
return;
123153
}
124154

125155
if (ProcessOutputType.isStdout(outputType)) {
@@ -141,11 +171,18 @@ public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType
141171
};
142172
}
143173

144-
private static GeneralCommandLine getMakeCommandLinde() {
174+
private void showServerError(String errorText, Consumer<ServerProgressPanel> onServerTerminated) {
175+
onServerTerminated.accept(activeServerProgressPanel);
176+
LOG.info("Unable to start llama server:\n" + errorText);
177+
OverlayUtil.showClosableBalloon(errorText, MessageType.ERROR, activeServerProgressPanel);
178+
}
179+
180+
private static GeneralCommandLine getMakeCommandLine(List<String> additionalCompileParameters) {
145181
GeneralCommandLine commandLine = new GeneralCommandLine().withCharset(StandardCharsets.UTF_8);
146182
commandLine.setExePath("make");
147183
commandLine.withWorkDirectory(CodeGPTPlugin.getLlamaSourcePath());
148184
commandLine.addParameters("-j");
185+
commandLine.addParameters(additionalCompileParameters);
149186
commandLine.setRedirectErrorStream(false);
150187
return commandLine;
151188
}
@@ -159,11 +196,16 @@ private GeneralCommandLine getServerCommandLine(LlamaServerStartupParams params)
159196
"-c", String.valueOf(params.contextLength()),
160197
"--port", String.valueOf(params.port()),
161198
"-t", String.valueOf(params.threads()));
162-
commandLine.addParameters(params.additionalParameters());
199+
commandLine.addParameters(params.additionalRunParameters());
163200
commandLine.setRedirectErrorStream(false);
164201
return commandLine;
165202
}
166203

204+
public void setActiveServerProgressPanel(
205+
ServerProgressPanel activeServerProgressPanel) {
206+
this.activeServerProgressPanel = activeServerProgressPanel;
207+
}
208+
167209
@Override
168210
public void dispose() {
169211
if (makeProcessHandler != null && !makeProcessHandler.isProcessTerminated()) {

src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerStartupParams.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
import java.util.List;
44

55
public record LlamaServerStartupParams(String modelPath, int contextLength, int threads, int port,
6-
List<String> additionalParameters) {
6+
List<String> additionalRunParameters,
7+
List<String> additionalBuildParameters) {
78
}

src/main/java/ee/carlrobert/codegpt/settings/service/llama/LlamaSettingsState.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class LlamaSettingsState {
2323
private int contextSize = 2048;
2424
private int threads = 8;
2525
private String additionalParameters = "";
26+
private String additionalBuildParameters = "";
2627
private int topK = 40;
2728
private double topP = 0.9;
2829
private double minP = 0.05;
@@ -138,6 +139,14 @@ public void setAdditionalParameters(String additionalParameters) {
138139
this.additionalParameters = additionalParameters;
139140
}
140141

142+
public String getAdditionalBuildParameters() {
143+
return additionalBuildParameters;
144+
}
145+
146+
public void setAdditionalBuildParameters(String additionalBuildParameters) {
147+
this.additionalBuildParameters = additionalBuildParameters;
148+
}
149+
141150
public int getTopK() {
142151
return topK;
143152
}
@@ -220,6 +229,7 @@ public boolean equals(Object o) {
220229
&& Objects.equals(baseHost, that.baseHost)
221230
&& Objects.equals(serverPort, that.serverPort)
222231
&& Objects.equals(additionalParameters, that.additionalParameters)
232+
&& Objects.equals(additionalBuildParameters, that.additionalBuildParameters)
223233
&& codeCompletionsEnabled == that.codeCompletionsEnabled
224234
&& codeCompletionMaxTokens == that.codeCompletionMaxTokens;
225235
}
@@ -229,7 +239,7 @@ public int hashCode() {
229239
return Objects.hash(runLocalServer, useCustomModel, customLlamaModelPath, huggingFaceModel,
230240
localModelPromptTemplate, remoteModelPromptTemplate, localModelInfillPromptTemplate,
231241
remoteModelInfillPromptTemplate, baseHost, serverPort, contextSize, threads,
232-
additionalParameters, topK, topP, minP, repeatPenalty, codeCompletionsEnabled,
233-
codeCompletionMaxTokens);
242+
additionalParameters, additionalBuildParameters, topK, topP, minP, repeatPenalty,
243+
codeCompletionsEnabled, codeCompletionMaxTokens);
234244
}
235245
}

src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaServerPreferencesForm.java

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public class LlamaServerPreferencesForm {
5757
private final IntegerField maxTokensField;
5858
private final IntegerField threadsField;
5959
private final JBTextField additionalParametersField;
60+
private final JBTextField additionalBuildParametersField;
6061
private final ChatPromptTemplatePanel remotePromptTemplatePanel;
6162
private final InfillPromptTemplatePanel infillPromptTemplatePanel;
6263

@@ -79,6 +80,9 @@ public LlamaServerPreferencesForm(LlamaSettingsState settings) {
7980
additionalParametersField = new JBTextField(settings.getAdditionalParameters(), 30);
8081
additionalParametersField.setEnabled(!serverRunning);
8182

83+
additionalBuildParametersField = new JBTextField(settings.getAdditionalBuildParameters(), 30);
84+
additionalBuildParametersField.setEnabled(!serverRunning);
85+
8286
baseHostField = new JBTextField(settings.getBaseHost(), 30);
8387
apiKeyField = new JBPasswordField();
8488
apiKeyField.setColumns(30);
@@ -124,6 +128,7 @@ public void resetForm(LlamaSettingsState state) {
124128
maxTokensField.setValue(state.getContextSize());
125129
threadsField.setValue(state.getThreads());
126130
additionalParametersField.setText(state.getAdditionalParameters());
131+
additionalBuildParametersField.setText(state.getAdditionalBuildParameters());
127132
remotePromptTemplatePanel.setPromptTemplate(state.getRemoteModelPromptTemplate()); // ?
128133
infillPromptTemplatePanel.setPromptTemplate(state.getRemoteModelInfillPromptTemplate());
129134
apiKeyField.setText(CredentialsStore.INSTANCE.getCredential(LLAMA_API_KEY));
@@ -184,9 +189,17 @@ public JComponent createRunLocalServerForm(LlamaServerAgent llamaServerAgent) {
184189
createComment("settingsConfigurable.service.llama.threads.comment"))
185190
.addLabeledComponent(
186191
CodeGPTBundle.get("settingsConfigurable.service.llama.additionalParameters.label"),
187-
additionalParametersField)
188-
.addComponentToRightColumn(
189-
createComment("settingsConfigurable.service.llama.additionalParameters.comment"))
192+
additionalParametersField)
193+
.addComponentToRightColumn(
194+
createComment(
195+
"settingsConfigurable.service.llama.additionalParameters.comment"))
196+
.addLabeledComponent(
197+
CodeGPTBundle.get(
198+
"settingsConfigurable.service.llama.additionalBuildParameters.label"),
199+
additionalBuildParametersField)
200+
.addComponentToRightColumn(
201+
createComment(
202+
"settingsConfigurable.service.llama.additionalBuildParameters.comment"))
190203
.addVerticalGap(4)
191204
.addComponentFillVertically(new JPanel(), 0)
192205
.getPanel()))
@@ -196,6 +209,7 @@ public JComponent createRunLocalServerForm(LlamaServerAgent llamaServerAgent) {
196209
private JButton getServerButton(
197210
LlamaServerAgent llamaServerAgent,
198211
ServerProgressPanel serverProgressPanel) {
212+
llamaServerAgent.setActiveServerProgressPanel(serverProgressPanel);
199213
var serverRunning = llamaServerAgent.isServerRunning();
200214
var serverButton = new JButton();
201215
serverButton.setText(serverRunning
@@ -218,7 +232,9 @@ private JButton getServerButton(
218232
getContextSize(),
219233
getThreads(),
220234
getServerPort(),
221-
getListOfAdditionalParameters()),
235+
getListOfAdditionalParameters(),
236+
getListOfAdditionalBuildParameters()
237+
),
222238
serverProgressPanel,
223239
() -> {
224240
setFormEnabled(false);
@@ -227,12 +243,12 @@ private JButton getServerButton(
227243
Actions.Checked,
228244
SwingConstants.LEADING));
229245
},
230-
() -> {
246+
(activeServerProgressPanel) -> {
231247
setFormEnabled(true);
232248
serverButton.setText(
233249
CodeGPTBundle.get("settingsConfigurable.service.llama.startServer.label"));
234250
serverButton.setIcon(Actions.Execute);
235-
serverProgressPanel.displayComponent(new JBLabel(
251+
activeServerProgressPanel.displayComponent(new JBLabel(
236252
CodeGPTBundle.get("settingsConfigurable.service.llama.progress.serverTerminated"),
237253
Actions.Cancel,
238254
SwingConstants.LEADING));
@@ -282,7 +298,7 @@ private void enableForm(JButton serverButton, ServerProgressPanel progressPanel)
282298
serverButton.setText(
283299
CodeGPTBundle.get("settingsConfigurable.service.llama.startServer.label"));
284300
serverButton.setIcon(Actions.Execute);
285-
progressPanel.updateText(
301+
progressPanel.displayText(
286302
CodeGPTBundle.get("settingsConfigurable.service.llama.progress.stoppingServer"));
287303
}
288304

@@ -291,7 +307,7 @@ private void disableForm(JButton serverButton, ServerProgressPanel progressPanel
291307
serverButton.setText(
292308
CodeGPTBundle.get("settingsConfigurable.service.llama.stopServer.label"));
293309
serverButton.setIcon(Actions.Suspend);
294-
progressPanel.startProgress(
310+
progressPanel.displayText(
295311
CodeGPTBundle.get("settingsConfigurable.service.llama.progress.startingServer"));
296312
}
297313

@@ -301,6 +317,7 @@ private void setFormEnabled(boolean enabled) {
301317
maxTokensField.setEnabled(enabled);
302318
threadsField.setEnabled(enabled);
303319
additionalParametersField.setEnabled(enabled);
320+
additionalBuildParametersField.setEnabled(enabled);
304321
}
305322

306323
public boolean isRunLocalServer() {
@@ -337,9 +354,20 @@ public String getAdditionalParameters() {
337354

338355
public List<String> getListOfAdditionalParameters() {
339356
return Arrays.stream(additionalParametersField.getText().split(","))
340-
.map(String::trim)
341-
.filter(s -> !s.isBlank())
342-
.toList();
357+
.map(String::trim)
358+
.filter(s -> !s.isBlank())
359+
.toList();
360+
}
361+
362+
public String getAdditionalBuildParameters() {
363+
return additionalBuildParametersField.getText();
364+
}
365+
366+
public List<String> getListOfAdditionalBuildParameters() {
367+
return Arrays.stream(additionalBuildParametersField.getText().split(","))
368+
.map(String::trim)
369+
.filter(s -> !s.isBlank())
370+
.toList();
343371
}
344372

345373
public PromptTemplate getPromptTemplate() {

src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaSettingsForm.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public LlamaSettingsState getCurrentState() {
4141
state.setContextSize(llamaServerPreferencesForm.getContextSize());
4242
state.setThreads(llamaServerPreferencesForm.getThreads());
4343
state.setAdditionalParameters(llamaServerPreferencesForm.getAdditionalParameters());
44+
state.setAdditionalBuildParameters(llamaServerPreferencesForm.getAdditionalBuildParameters());
4445

4546
var modelPreferencesForm = llamaServerPreferencesForm.getLlamaModelPreferencesForm();
4647
state.setCustomLlamaModelPath(modelPreferencesForm.getCustomLlamaModelPath());

0 commit comments

Comments
 (0)