From e4746248dd038c4c41e923f2f161bcf2118438cd Mon Sep 17 00:00:00 2001 From: extio-de Date: Fri, 24 Apr 2026 21:35:21 +0200 Subject: [PATCH] Add model creation time and implement model tree view in UI --- lm-launcher.jar | Bin 2179444 -> 2179542 bytes src/de/extio/lm_launcher/Data.java | 48 +++- src/de/extio/lm_launcher/LaunchFrame.java | 240 +++++++++--------- src/de/extio/lm_launcher/Model.java | 2 +- .../lm_launcher/ModelPropertiesDialog.java | 4 +- 5 files changed, 171 insertions(+), 123 deletions(-) diff --git a/lm-launcher.jar b/lm-launcher.jar index 8ffc1c1edab66b7a2583d67e8bea115d75d1a86c..b729e03f2d1e70fd56a688611db9d9612b9c32a2 100644 GIT binary patch delta 29772 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

MS$cLiqm(cw$v=Jy+4=cV1>pHZvt5z`@_* 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 AJ^%m! diff --git a/src/de/extio/lm_launcher/Data.java b/src/de/extio/lm_launcher/Data.java index aca833e..bd6e35a 100644 --- a/src/de/extio/lm_launcher/Data.java +++ b/src/de/extio/lm_launcher/Data.java @@ -5,6 +5,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -45,7 +47,7 @@ public class Data { for (int i = 0; i < modelData.models().size(); i++) { final Model model = modelData.models.get(i); if (model.maxContextSize() < model.contextSize() || model.promptTemplate() == null) { - modelData.models.set(i, new Model(model.path(), model.contextSize(), model.contextSize(), model.gpuLayers(), model.threads(), Objects.requireNonNullElse(model.promptTemplate(), ""))); + modelData.models.set(i, new Model(model.path(), model.contextSize(), model.contextSize(), model.gpuLayers(), model.threads(), Objects.requireNonNullElse(model.promptTemplate(), ""), model.ctime())); } } sortModels(); @@ -83,8 +85,9 @@ public class Data { static void sortModels() { modelData.models().sort(Comparator - .comparing(Data::modelName, String.CASE_INSENSITIVE_ORDER) - .thenComparing(Model::path)); + .comparing(m -> Path.of(m.path()).getParent().toString()) + .thenComparing(Model::ctime).reversed() + .thenComparing(Data::modelName, String.CASE_INSENSITIVE_ORDER)); } static void saveApps() { @@ -103,24 +106,57 @@ public class Data { } static List scanModels() { - final List result = new ArrayList<>(); + return scanModelPaths().stream().map(p -> p.toString()).toList(); + } + + static List scanModelPaths() { + final List result = new ArrayList<>(); try { try (var paths = Files.walk(Path.of(props.getProperty("models")))) { paths .filter(Files::isRegularFile) .filter(p -> p.getFileName().toString().endsWith(".gguf")) .map(Path::toAbsolutePath) - .map(Path::toString) - .sorted() + .map(Path::normalize) .forEach(result::add); } } catch (final IOException e) { e.printStackTrace(); } + // Sort by parent path (alphabetical), then by file ctime within the same directory + result.sort(Comparator + .comparing(p -> p.getParent().toString()) + .thenComparing(p -> { + try { + return Files.readAttributes(p, BasicFileAttributes.class).creationTime(); + } + catch (final IOException e) { + return FileTime.fromMillis(0); + } + }).reversed() + .thenComparing(Path::toString)); return result; } + static Model findModelByPath(final String path) { + return modelData.models().stream() + .filter(m -> m.path().equals(path)) + .findFirst() + .orElse(null); + } + + static Model defaultModel(final String path) { + long ctime = 0; + try { + ctime = Files.readAttributes(Path.of(path), BasicFileAttributes.class).creationTime().toMillis(); + } + catch (final IOException e) { + // Use 0 as fallback + } + return new Model(path, 16000, 128000, 99, 6, "", ctime); + } + static record ModelData(List models) { } diff --git a/src/de/extio/lm_launcher/LaunchFrame.java b/src/de/extio/lm_launcher/LaunchFrame.java index cb4e532..e228661 100644 --- a/src/de/extio/lm_launcher/LaunchFrame.java +++ b/src/de/extio/lm_launcher/LaunchFrame.java @@ -1,6 +1,7 @@ package de.extio.lm_launcher; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.GridLayout; @@ -9,7 +10,9 @@ import java.awt.event.ActionListener; import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.swing.AbstractCellEditor; import javax.swing.Box; @@ -27,6 +30,7 @@ import javax.swing.JScrollPane; import javax.swing.JSlider; import javax.swing.JSplitPane; import javax.swing.JTable; +import javax.swing.JTree; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.WindowConstants; @@ -34,6 +38,11 @@ import javax.swing.border.EmptyBorder; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; public class LaunchFrame extends JFrame { @@ -57,7 +66,7 @@ public class LaunchFrame extends JFrame { JList list; - JList list_1; + JTree modelTree; JButton btnDelete; @@ -77,8 +86,6 @@ public class LaunchFrame extends JFrame { DefaultListModel listModel; - DefaultListModel list1Model; - Component horizontalStrut; JSplitPane splitPane_1; @@ -133,50 +140,33 @@ public class LaunchFrame extends JFrame { { this.panel = new JPanel(); this.contentPane.add(this.panel, BorderLayout.SOUTH); - { - this.btnAdd = new JButton("Add"); - this.btnAdd.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(final ActionEvent e) { - final SelectModelDialog smDialog = new SelectModelDialog(LaunchFrame.this, path -> { - final ModelPropertiesDialog mpDialog = new ModelPropertiesDialog(LaunchFrame.this, path, null, model -> { - Data.modelData.models().add(model); - try { - Data.saveModels(); - } - finally { - LaunchFrame.this.refresh(); - } - }); - mpDialog.setLocationRelativeTo(LaunchFrame.this); - mpDialog.setVisible(true); - }); - smDialog.setLocationRelativeTo(LaunchFrame.this); - smDialog.setVisible(true); - } - }); - this.panel.add(this.btnAdd); - } { this.btnEdit = new JButton("Edit"); this.btnEdit.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { - final int index = LaunchFrame.this.list_1.getSelectedIndex(); - if (index == -1) { + final String selectedPath = LaunchFrame.this.getSelectedModelPath(); + if (selectedPath == null) { JOptionPane.showMessageDialog(LaunchFrame.this, "Error: Select a model first", "Error Message", JOptionPane.ERROR_MESSAGE); return; } - final Model editModel = Data.modelData.models().get(index); - final ModelPropertiesDialog mpDialog = new ModelPropertiesDialog(LaunchFrame.this, editModel.path(), editModel, model -> { - Data.modelData.models().set(index, model); + final Model existingModel = Data.findModelByPath(selectedPath); + final Model editModel = existingModel != null ? existingModel : Data.defaultModel(selectedPath); + final ModelPropertiesDialog mpDialog = new ModelPropertiesDialog(LaunchFrame.this, selectedPath, editModel, model -> { + // Replace or add model params + final int idx = Data.modelData.models().indexOf(existingModel); + if (idx >= 0) { + Data.modelData.models().set(idx, model); + } + else { + Data.modelData.models().add(model); + } try { Data.saveModels(); } finally { - LaunchFrame.this.refresh(); + LaunchFrame.this.refreshModelSliders(model); } }); mpDialog.setLocationRelativeTo(LaunchFrame.this); @@ -185,51 +175,6 @@ public class LaunchFrame extends JFrame { }); this.panel.add(this.btnEdit); } - { - this.btnDelete = new JButton("Delete"); - this.btnDelete.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(final ActionEvent e) { - final int index = LaunchFrame.this.list_1.getSelectedIndex(); - if (index == -1) { - JOptionPane.showMessageDialog(LaunchFrame.this, "Error: Select a model first", "Error Message", JOptionPane.ERROR_MESSAGE); - return; - } - Data.modelData.models().remove(index); - try { - Data.saveModels(); - } - finally { - LaunchFrame.this.refresh(); - } - } - }); - this.panel.add(this.btnDelete); - } - { - this.btnClone = new JButton("Clone"); - this.btnClone.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(final ActionEvent e) { - final int index = LaunchFrame.this.list_1.getSelectedIndex(); - if (index == -1) { - JOptionPane.showMessageDialog(LaunchFrame.this, "Error: Select a model first", "Error Message", JOptionPane.ERROR_MESSAGE); - return; - } - final Model model = Data.modelData.models().get(index); - Data.modelData.models().add(index, new Model(model.path(), model.contextSize(), model.maxContextSize(), model.gpuLayers(), model.threads(), model.promptTemplate())); - try { - Data.saveModels(); - } - finally { - LaunchFrame.this.refresh(); - } - } - }); - this.panel.add(this.btnClone); - } } { this.panel_1 = new JPanel(); @@ -289,32 +234,26 @@ public class LaunchFrame extends JFrame { this.scrollPane_1 = new JScrollPane(); this.splitPane_2.setLeftComponent(this.scrollPane_1); - this.list1Model = new DefaultListModel<>(); - this.list_1 = new JList(this.list1Model); - this.list_1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - this.list_1.getSelectionModel().addListSelectionListener(e -> { - if (!e.getValueIsAdjusting()) { - final DefaultListSelectionModel selectionModel = (DefaultListSelectionModel) e.getSource(); - if (selectionModel.getMinSelectionIndex() > -1) { - final Model model = Data.modelData.models().get(selectionModel.getMinSelectionIndex()); - - this.slider_context.setMaximum(model.maxContextSize()); - this.slider_context.setMajorTickSpacing(model.maxContextSize() / 4); - this.slider_context.setMinorTickSpacing(model.maxContextSize() / 16); - this.slider_context.setValue(model.contextSize()); - this.slider_context.setLabelTable(this.slider_context.createStandardLabels(model.maxContextSize() / 4)); - this.slider_context.setSnapToTicks(true); - this.slider_context.repaint(); - - this.slider_threads.setValue(model.threads()); - - this.slider_gpu.setValue(model.gpuLayers()); - - this.lblPromptTemplate_1.setText(model.promptTemplate()); - } + + // Tree view for models + this.modelTree = new JTree(new DefaultMutableTreeNode("Models")); + this.modelTree.setRootVisible(false); + this.modelTree.setShowsRootHandles(true); + this.modelTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + this.modelTree.setCellRenderer(new ModelTreeCellRenderer()); + // Set smaller font for tree to account for UI scaling + this.modelTree.setFont(this.modelTree.getFont().deriveFont(10f)); + this.modelTree.addTreeSelectionListener(e -> { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode) this.modelTree.getLastSelectedPathComponent(); + if (node != null && node.isLeaf() && node.getUserObject() instanceof Path) { + final Path p = (Path) node.getUserObject(); + final Model saved = Data.findModelByPath(p.toString()); + final Model model = saved != null ? saved : Data.defaultModel(p.toString()); + this.refreshModelSliders(model); } }); - this.scrollPane_1.setViewportView(this.list_1); + this.scrollPane_1.setViewportView(this.modelTree); + { this.panel_3 = new JPanel(); this.splitPane_2.setRightComponent(this.panel_3); @@ -498,16 +437,18 @@ public class LaunchFrame extends JFrame { final App app = Data.appData.apps().get(AppIndex); Model model = null; - final int modelIndex = LaunchFrame.this.list_1.getSelectedIndex(); - if (modelIndex > -1) { - final Model template = Data.modelData.models().get(modelIndex); + final String selectedPath = LaunchFrame.this.getSelectedModelPath(); + if (selectedPath != null) { + final Model saved = Data.findModelByPath(selectedPath); + final Model template = saved != null ? saved : Data.defaultModel(selectedPath); model = new Model( template.path(), LaunchFrame.this.slider_context.getValue(), template.maxContextSize(), LaunchFrame.this.slider_gpu.getValue(), LaunchFrame.this.slider_threads.getValue(), - template.promptTemplate()); + template.promptTemplate(), + template.ctime()); } final List argumentOverrides = new ArrayList<>(); @@ -550,28 +491,97 @@ public class LaunchFrame extends JFrame { this.refresh(); } + /** Returns the absolute path string of the currently selected model leaf node, or null. */ + private String getSelectedModelPath() { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode) this.modelTree.getLastSelectedPathComponent(); + if (node != null && node.isLeaf() && node.getUserObject() instanceof Path) { + return ((Path) node.getUserObject()).toString(); + } + return null; + } + + private void refreshModelSliders(final Model model) { + this.slider_context.setMaximum(model.maxContextSize()); + this.slider_context.setMajorTickSpacing(Math.max(1, model.maxContextSize() / 4)); + this.slider_context.setMinorTickSpacing(Math.max(1, model.maxContextSize() / 16)); + this.slider_context.setValue(model.contextSize()); + this.slider_context.setLabelTable(this.slider_context.createStandardLabels(Math.max(1, model.maxContextSize() / 4))); + this.slider_context.setSnapToTicks(true); + this.slider_context.repaint(); + + this.slider_threads.setValue(model.threads()); + this.slider_gpu.setValue(model.gpuLayers()); + this.lblPromptTemplate_1.setText(model.promptTemplate() != null && !model.promptTemplate().isEmpty() ? model.promptTemplate() : "-"); + } + private void refresh() { - Data.sortModels(); + // Rebuild apps list this.listModel.clear(); Data.appData.apps() .stream() .map(app -> app.path().getFileName() + " " + app.path().getParent() + " " + app.interpreter()) .forEach(this.listModel::addElement); - this.list1Model.clear(); - Data.modelData.models() - .stream() - .map(model -> Path.of(model.path()).getFileName() + "; ctx " + model.contextSize() + "/" + model.maxContextSize()) - .forEach(this.list1Model::addElement); - if (this.table.getCellEditor() != null) { this.table.getCellEditor().stopCellEditing(); } this.appArgumentsTableModel.setRowCount(0); + // Rebuild model tree from filesystem + final String baseStr = Data.props.getProperty("models"); + if (baseStr != null) { + final Path base = Path.of(baseStr).toAbsolutePath().normalize(); + final DefaultMutableTreeNode root = new DefaultMutableTreeNode(base); + final Map nodeMap = new HashMap<>(); + nodeMap.put(base, root); + + for (final Path modelPath : Data.scanModelPaths()) { + final Path rel = base.relativize(modelPath); + DefaultMutableTreeNode current = root; + Path currentAbs = base; + for (int i = 0; i < rel.getNameCount(); i++) { + currentAbs = currentAbs.resolve(rel.getName(i)); + if (!nodeMap.containsKey(currentAbs)) { + final DefaultMutableTreeNode node = new DefaultMutableTreeNode(currentAbs); + current.add(node); + nodeMap.put(currentAbs, node); + } + current = nodeMap.get(currentAbs); + } + } + + this.modelTree.setModel(new DefaultTreeModel(root)); + } + this.repaint(); } + /** Tree cell renderer: shows only the last path component (file/folder name). */ + static class ModelTreeCellRenderer extends DefaultTreeCellRenderer { + + @Override + public Component getTreeCellRendererComponent(final JTree tree, final Object value, final boolean sel, + final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + if (value instanceof DefaultMutableTreeNode) { + final Object userObj = ((DefaultMutableTreeNode) value).getUserObject(); + if (userObj instanceof Path) { + final Path p = (Path) userObj; + final Path filename = p.getFileName(); + setText(filename != null ? filename.toString() : p.toString()); + // Highlight models with saved params + if (leaf) { + final Model saved = Data.findModelByPath(p.toString()); + if (saved != null) { + setForeground(sel ? Color.WHITE : new Color(0, 100, 0)); + } + } + } + } + return this; + } + } + static class AppArgumentsJCheckBoxRenderer extends JCheckBox implements TableCellRenderer { private final DefaultTableModel model; @@ -617,4 +627,4 @@ public class LaunchFrame extends JFrame { } } -} \ No newline at end of file +} diff --git a/src/de/extio/lm_launcher/Model.java b/src/de/extio/lm_launcher/Model.java index a9b4229..089b959 100644 --- a/src/de/extio/lm_launcher/Model.java +++ b/src/de/extio/lm_launcher/Model.java @@ -1,4 +1,4 @@ package de.extio.lm_launcher; -record Model(String path, int contextSize, int maxContextSize, int gpuLayers, int threads, String promptTemplate) { +record Model(String path, int contextSize, int maxContextSize, int gpuLayers, int threads, String promptTemplate, long ctime) { } diff --git a/src/de/extio/lm_launcher/ModelPropertiesDialog.java b/src/de/extio/lm_launcher/ModelPropertiesDialog.java index 17ad9f7..e37b945 100644 --- a/src/de/extio/lm_launcher/ModelPropertiesDialog.java +++ b/src/de/extio/lm_launcher/ModelPropertiesDialog.java @@ -117,13 +117,15 @@ public class ModelPropertiesDialog extends JDialog { @Override public void actionPerformed(final ActionEvent e) { ModelPropertiesDialog.this.setVisible(false); + final Model modelToSave = editModel != null ? editModel : Data.defaultModel(modelPath); modelConsumer.accept( new Model(modelPath, Integer.parseInt(ModelPropertiesDialog.this.textField_3.getText()), Integer.parseInt(ModelPropertiesDialog.this.textField.getText()), Integer.parseInt(ModelPropertiesDialog.this.textField_1.getText()), Integer.parseInt(ModelPropertiesDialog.this.textField_2.getText()), - ModelPropertiesDialog.this.txtPrompttemplate.getText())); + ModelPropertiesDialog.this.txtPrompttemplate.getText(), + modelToSave.ctime())); ModelPropertiesDialog.this.dispose(); } });