some UI tweaks

This commit is contained in:
Radek Davidek 2026-04-22 17:01:38 +02:00
parent 9283f4e766
commit 9f909192d2
4 changed files with 145 additions and 142 deletions

View File

@ -1,5 +1,6 @@
#Llama Runner Configuration
#Tue Apr 14 16:56:36 CEST 2026
#Wed Apr 22 16:58:54 CEST 2026
lastProfile=Exaone4
windowHeight=1281
windowWidth=665
windowX=1895

View File

@ -21,28 +21,6 @@
"fit": false,
"reasoning": false
},
"Qwen3.5-q6k-180k": {
"host": "0.0.0.0",
"port": 3080,
"parallel": 1,
"batchSize": 2048,
"threads": 99,
"flashAttention": true,
"kvUnified": true,
"cacheTypeK": "q8_0",
"cacheTypeV": "q8_0",
"temperature": 0.6,
"topP": 0.95,
"topK": 20,
"minP": 0.0,
"ctxSize": 180000,
"enableThinking": false,
"modelPath": "/home/kamma/models/Qwen3.5-35B-A3B-Q6_K.gguf",
"chatTemplateKwargs": "{\"enable_thinking\": false}",
"ngl": 999,
"fit": true,
"reasoning": false
},
"QwenCoderNext-160k": {
"host": "0.0.0.0",
"port": 3080,
@ -87,28 +65,6 @@
"fit": false,
"reasoning": false
},
"Qwen3.5 q6xl 160k": {
"host": "0.0.0.0",
"port": 3080,
"parallel": 1,
"batchSize": 2048,
"threads": 99,
"flashAttention": true,
"kvUnified": true,
"cacheTypeK": "turbo3",
"cacheTypeV": "turbo3",
"temperature": 0.6,
"topP": 0.95,
"topK": 20,
"minP": 0.0,
"ctxSize": 160000,
"enableThinking": false,
"modelPath": "/home/kamma/models/Qwen3.5-35B-A3B-UD-Q6_K_XL.gguf",
"chatTemplateKwargs": "{\"enable_thinking\": false}",
"ngl": -1,
"fit": true,
"reasoning": false
},
"gpt-oss-20b-160k": {
"host": "0.0.0.0",
"port": 3080,
@ -175,46 +131,24 @@
"fit": true,
"reasoning": false
},
"Qwen3-Coder-Next-UD-Q2KXL-160k": {
"host": "0.0.0.0",
"port": 3080,
"parallel": 1,
"batchSize": 2048,
"threads": 99,
"flashAttention": true,
"kvUnified": true,
"cacheTypeK": "turbo3",
"cacheTypeV": "turbo3",
"temperature": 0.6,
"topP": 0.95,
"topK": 20,
"minP": 0.0,
"ctxSize": 160000,
"enableThinking": false,
"modelPath": "/home/kamma/models/Qwen3-Coder-Next-UD-Q2_K_XL.gguf",
"chatTemplateKwargs": "{\"enable_thinking\": true}",
"ngl": -1,
"fit": true,
"reasoning": false
},
"Qwen3-Coder-Next-UD-Q3KXL-160k": {
"host": "0.0.0.0",
"port": 3080,
"parallel": 1,
"batchSize": 2048,
"batchSize": 4096,
"threads": 99,
"flashAttention": true,
"kvUnified": true,
"cacheTypeK": "turbo3",
"cacheTypeV": "turbo3",
"temperature": 0.6,
"cacheTypeK": "q8_0",
"cacheTypeV": "q8_0",
"temperature": 1.0,
"topP": 0.95,
"topK": 20,
"minP": 0.0,
"topK": 40,
"minP": 0.01,
"ctxSize": 160000,
"enableThinking": false,
"modelPath": "/home/kamma/models/Qwen3-Coder-Next-UD-Q3_K_XL.gguf",
"chatTemplateKwargs": "{\"enable_thinking\": true}",
"chatTemplateKwargs": "",
"ngl": -1,
"fit": true,
"reasoning": false
@ -227,63 +161,19 @@
"threads": 99,
"flashAttention": true,
"kvUnified": true,
"cacheTypeK": "turbo3",
"cacheTypeV": "turbo3",
"temperature": 0.6,
"cacheTypeK": "q8_0",
"cacheTypeV": "q8_0",
"temperature": 1.0,
"topP": 0.95,
"topK": 20,
"minP": 0.0,
"topK": 40,
"minP": 0.01,
"ctxSize": 160000,
"enableThinking": false,
"modelPath": "/home/kamma/models/Qwen3-Coder-Next-UD-Q4_K_XL.gguf",
"chatTemplateKwargs": "",
"ngl": -1,
"fit": true,
"reasoning": true
},
"Qwen35-35B-A3B-Q6K-turbo4-256k": {
"host": "0.0.0.0",
"port": 3080,
"parallel": 1,
"batchSize": 2048,
"threads": 99,
"flashAttention": true,
"kvUnified": true,
"cacheTypeK": "q8_0",
"cacheTypeV": "q8_0",
"temperature": 0.6,
"topP": 0.95,
"topK": 20,
"minP": 0.0,
"ctxSize": 256000,
"enableThinking": false,
"modelPath": "/home/kamma/models/Qwen3.5-35B-A3B-Q6_K.gguf",
"chatTemplateKwargs": "{\"enable_thinking\": true}",
"ngl": 999,
"fit": true,
"reasoning": true
},
"Qwen35-35B-A3B-Q6K-Q8-256k": {
"host": "0.0.0.0",
"port": 3080,
"parallel": 1,
"batchSize": 2048,
"threads": 99,
"flashAttention": true,
"kvUnified": true,
"cacheTypeK": "q8_0",
"cacheTypeV": "q8_0",
"temperature": 0.6,
"topP": 0.95,
"topK": 20,
"minP": 0.0,
"ctxSize": 256000,
"enableThinking": false,
"modelPath": "/home/kamma/models/Qwen3.5-35B-A3B-Q6_K.gguf",
"chatTemplateKwargs": "",
"ngl": 999,
"fit": true,
"reasoning": true
"reasoning": false
},
"gemma-4-31B-it-UD-Q6KXL-54k": {
"host": "0.0.0.0",
@ -350,5 +240,71 @@
"ngl": 99,
"fit": false,
"reasoning": true
},
"Exaone4": {
"host": "0.0.0.0",
"port": 3080,
"parallel": 1,
"batchSize": 2048,
"threads": 99,
"flashAttention": true,
"kvUnified": true,
"cacheTypeK": "q8_0",
"cacheTypeV": "q8_0",
"temperature": 0.9,
"topP": 0.95,
"topK": 20,
"minP": 0.0,
"ctxSize": 131072,
"enableThinking": false,
"modelPath": "/home/kamma/models/EXAONE-4.0-32B-GGUF-Q6_K.gguf",
"chatTemplateKwargs": "",
"ngl": 99,
"fit": false,
"reasoning": true
},
"Qwen3.6-35B-A3B-UD-Q6_K_XL-FIT": {
"host": "0.0.0.0",
"port": 3080,
"parallel": 1,
"batchSize": 4096,
"threads": 99,
"flashAttention": true,
"kvUnified": true,
"cacheTypeK": "q8_0",
"cacheTypeV": "q8_0",
"temperature": 0.9,
"topP": 0.95,
"topK": 20,
"minP": 0.0,
"ctxSize": 180000,
"enableThinking": false,
"modelPath": "/home/kamma/models/Qwen3.6-35B-A3B-UD-Q6_K_XL.gguf",
"chatTemplateKwargs": "",
"ngl": 99,
"fit": false,
"reasoning": true
},
"Qwen3.6-35B-A3B-UD-Q5_K_XL-FULL": {
"host": "0.0.0.0",
"port": 3080,
"parallel": 1,
"batchSize": 4096,
"threads": 99,
"flashAttention": true,
"kvUnified": true,
"cacheTypeK": "q8_0",
"cacheTypeV": "q8_0",
"temperature": 0.9,
"topP": 0.95,
"topK": 20,
"minP": 0.0,
"ctxSize": 180000,
"enableThinking": false,
"modelPath": "/home/kamma/models/Qwen3.6-35B-A3B-UD-Q5_K_XL.gguf",
"chatTemplateKwargs": "",
"ngl": 99,
"fit": false,
"reasoning": true
}
}

View File

@ -19,6 +19,7 @@ public class AppConfig {
private int windowHeight;
private int windowX;
private int windowY;
private String lastProfile;
private final ConfigLocation configLocation;
public AppConfig() {
@ -47,6 +48,7 @@ public class AppConfig {
windowHeight = Integer.parseInt(props.getProperty("windowHeight", String.valueOf(DEFAULT_HEIGHT)));
windowX = Integer.parseInt(props.getProperty("windowX", String.valueOf(DEFAULT_X)));
windowY = Integer.parseInt(props.getProperty("windowY", String.valueOf(DEFAULT_Y)));
lastProfile = props.getProperty("lastProfile", "");
} catch (IOException | NumberFormatException e) {
// Use default values on error
}
@ -60,6 +62,9 @@ public class AppConfig {
props.setProperty("windowHeight", String.valueOf(windowHeight));
props.setProperty("windowX", String.valueOf(windowX));
props.setProperty("windowY", String.valueOf(windowY));
if (lastProfile != null) {
props.setProperty("lastProfile", lastProfile);
}
try (FileOutputStream fos = new FileOutputStream(configLocation.getConfigPropertiesFile())) {
props.store(fos, "Llama Runner Configuration");
@ -99,4 +104,12 @@ public class AppConfig {
public void setWindowY(int windowY) {
this.windowY = windowY;
}
public String getLastProfile() {
return lastProfile;
}
public void setLastProfile(String lastProfile) {
this.lastProfile = lastProfile;
}
}

View File

@ -13,6 +13,8 @@ import java.awt.Toolkit;
import java.awt.Image;
import javax.imageio.ImageIO;
import java.awt.datatransfer.StringSelection;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
@ -130,6 +132,10 @@ public class Main extends JFrame {
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
String profile = (String) profileComboBox.getSelectedItem();
if (profile != null) {
appConfig.setLastProfile(profile);
}
saveWindowConfig();
dispose();
System.exit(0);
@ -140,8 +146,12 @@ public class Main extends JFrame {
SwingUtilities.invokeLater(() -> {
loadModels();
loadProfiles();
if (profileComboBox.getItemCount() > 0) {
if (appConfig.getLastProfile() != null && !appConfig.getLastProfile().isEmpty()) {
profileComboBox.setSelectedItem(appConfig.getLastProfile());
} else if (profileComboBox.getItemCount() > 0) {
profileComboBox.setSelectedIndex(0);
}
if (profileComboBox.getSelectedItem() != null) {
showLoadProfileDialog();
}
updateCommandPreview();
@ -291,16 +301,23 @@ public class Main extends JFrame {
}
private void loadProfiles() {
String selectedItem = (String) profileComboBox.getSelectedItem();
// Remove listener temporarily to prevent triggering during load
profileComboBox.removeActionListener(profileChangeListener);
try {
profileComboBox.removeAllItems();
List<String> profiles = profileManager.listProfiles();
profiles.sort(String::compareToIgnoreCase);
for (String name : profiles) {
profileComboBox.addItem(name);
}
if (selectedItem != null) {
profileComboBox.setSelectedItem(selectedItem);
}
// Re-add listener after loading
profileComboBox.addActionListener(profileChangeListener);
} catch (Exception e) {
@ -318,6 +335,7 @@ public class Main extends JFrame {
}
String selectedItem = (String) profileComboBox.getSelectedItem();
if (selectedItem != null && !selectedItem.isEmpty()) {
appConfig.setLastProfile(selectedItem);
showLoadProfileDialog();
}
}
@ -349,6 +367,7 @@ public class Main extends JFrame {
return;
}
saveProfileToName(currentProfile);
loadProfiles();
JOptionPane.showMessageDialog(this, "Profile saved!");
} catch (IOException e) {
@ -641,7 +660,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
hostField = new JTextField("0.0.0.0", 15);
hostField.setCaretColor(Color.WHITE);
hostField.addActionListener(e -> updateCommandPreview());
addFocusUpdateListener(hostField);
panel.add(hostField, gbc);
gbc.gridx = 0;
@ -653,7 +672,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
portField = new JTextField("3080", 10);
portField.setCaretColor(Color.WHITE);
portField.addActionListener(e -> updateCommandPreview());
addFocusUpdateListener(portField);
panel.add(portField, gbc);
return panel;
@ -677,7 +696,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
parallelField = new JTextField("1", 10);
parallelField.setCaretColor(Color.WHITE);
parallelField.addActionListener(e -> updateCommandPreview());
addFocusUpdateListener(parallelField);
panel.add(parallelField, gbc);
gbc.gridx = 0;
@ -689,7 +708,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
batchSizeField = new JTextField("4096", 10);
batchSizeField.setCaretColor(Color.WHITE);
batchSizeField.addActionListener(e -> updateCommandPreview());
addFocusUpdateListener(batchSizeField);
panel.add(batchSizeField, gbc);
gbc.gridx = 0;
@ -701,7 +720,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
threadsField = new JTextField("99", 10);
threadsField.setCaretColor(Color.WHITE);
threadsField.addActionListener(e -> updateCommandPreview());
addFocusUpdateListener(threadsField);
panel.add(threadsField, gbc);
gbc.gridx = 0;
@ -769,7 +788,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
nglField = new JTextField("-1", 10);
nglField.setCaretColor(Color.WHITE);
nglField.getDocument().addDocumentListener(createNglDocumentListener());
addFocusUpdateListener(nglField);
panel.add(nglField, gbc);
// Fit parameter
@ -816,7 +835,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
tempField = new JTextField("0.6", 10);
tempField.setCaretColor(Color.WHITE);
tempField.addActionListener(e -> updateCommandPreview());
addFocusUpdateListener(tempField);
panel.add(tempField, gbc);
gbc.gridx = 0;
@ -828,7 +847,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
topPField = new JTextField("0.95", 10);
topPField.setCaretColor(Color.WHITE);
topPField.addActionListener(e -> updateCommandPreview());
addFocusUpdateListener(topPField);
panel.add(topPField, gbc);
gbc.gridx = 0;
@ -840,7 +859,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
topKField = new JTextField("20", 10);
topKField.setCaretColor(Color.WHITE);
topKField.addActionListener(e -> updateCommandPreview());
addFocusUpdateListener(topKField);
panel.add(topKField, gbc);
gbc.gridx = 0;
@ -852,7 +871,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
minPField = new JTextField("0.00", 10);
minPField.setCaretColor(Color.WHITE);
minPField.addActionListener(e -> updateCommandPreview());
addFocusUpdateListener(minPField);
panel.add(minPField, gbc);
gbc.gridx = 0;
@ -864,8 +883,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
ctxSizeField = new JTextField("180000", 10);
ctxSizeField.setCaretColor(Color.WHITE);
ctxSizeField.addActionListener(e -> updateCommandPreview());
ctxSizeField.getDocument().addDocumentListener(new PreviewUpdateListener(this::updateCommandPreview));
addFocusUpdateListener(ctxSizeField);
panel.add(ctxSizeField, gbc);
gbc.gridx = 0;
@ -878,7 +896,7 @@ public class Main extends JFrame {
gbc.weightx = 1.0;
kwargsField = new JTextField("{\"enable_thinking\": true}");
kwargsField.setCaretColor(Color.WHITE);
kwargsField.getDocument().addDocumentListener(new PreviewUpdateListener(this::updateCommandPreview));
addFocusUpdateListener(kwargsField);
panel.add(kwargsField, gbc);
return panel;
@ -924,8 +942,18 @@ public class Main extends JFrame {
if (isProfileLoading) {
return;
}
String command = buildCommand();
commandPreviewArea.setText(command);
try {
String error = validateCurrentConfig();
if (error != null) {
JOptionPane.showMessageDialog(this, error, "Validation Error", JOptionPane.ERROR_MESSAGE);
return;
}
String command = buildCommand();
commandPreviewArea.setText(command);
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(this, "Please enter valid numeric values.", "Validation Error",
JOptionPane.ERROR_MESSAGE);
}
}
private void setNglFieldText(String text) {
@ -933,8 +961,13 @@ public class Main extends JFrame {
updateCommandPreview();
}
private javax.swing.event.DocumentListener createNglDocumentListener() {
return new PreviewUpdateListener(this::updateCommandPreview);
private void addFocusUpdateListener(JTextField field) {
field.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
updateCommandPreview();
}
});
}
private void copyCommandToClipboard() {