diff --git a/packages/chat-client/src/components/SettingsView.jsx b/packages/chat-client/src/components/SettingsView.jsx
index 20ecd29..1207223 100644
--- a/packages/chat-client/src/components/SettingsView.jsx
+++ b/packages/chat-client/src/components/SettingsView.jsx
@@ -138,7 +138,7 @@ function NumberSetting({ label, description, value, min, max, step = 1, onSave,
function SettingsRow({ label, description, action }) {
return (
{
+ const { modelsFolderPath } = appSettings.load();
+
try {
- const raw = fs.readFileSync(MODELS_PATH, 'utf8');
- const models = JSON.parse(raw);
+ // Try scanning folder for .gguf files
+ const files = fs.readdirSync(modelsFolderPath)
+ .filter(f => f.endsWith('.gguf'));
+
+ // Try loading models.json for richer metadata (label, description)
+ let manifest = {};
+ try {
+ const manifestPath = path.join(modelsFolderPath, 'models.json');
+ const raw = fs.readFileSync(manifestPath, 'utf8');
+ // Index manifest by filename for quick lookup
+ const list = JSON.parse(raw);
+ for (const m of list) {
+ manifest[m.value] = m;
+ }
+ } catch {
+ // No manifest — scan only, that's fine
+ }
+
+ const models = files.map(filename => ({
+ value: filename,
+ label: manifest[filename]?.label ?? filename.replace('.gguf', ''),
+ description: manifest[filename]?.description ?? null,
+ size: getFileSizeMB(path.join(modelsFolderPath, filename)),
+ }));
+
res.json(models);
} catch (err) {
- console.error('[models] Failed to read manifest:', err.message);
- res.status(500).json({ error: 'Could not load models manifest' });
+ console.error('[models] Failed to scan folder:', err.message);
+ res.status(500).json({ error: `Could not read models folder: ${modelsFolderPath}` });
}
});
+function getFileSizeMB(filepath) {
+ try {
+ const bytes = fs.statSync(filepath).size;
+ return (bytes / (1024 ** 3)).toFixed(1) + ' GB'; // models are big — show GB
+ } catch {
+ return null;
+ }
+}
+
module.exports = router;
\ No newline at end of file
diff --git a/packages/orchestration-service/src/routes/settings.js b/packages/orchestration-service/src/routes/settings.js
index 8a7c977..4a5ba13 100644
--- a/packages/orchestration-service/src/routes/settings.js
+++ b/packages/orchestration-service/src/routes/settings.js
@@ -1,5 +1,6 @@
const { Router } = require('express');
const settings = require('../config/settings');
+const fs = require('fs');
const router = Router();
@@ -32,6 +33,18 @@ router.patch('/', (req, res) => {
updates.scoreThreshold = val;
}
+ if (req.body.modelsFolderPath !== undefined) {
+ const val = req.body.modelsFolderPath.trim();
+ if (!val) return res.status(400).json({ error: 'modelsFolderPath cannot be empty' });
+ // Verify the path exists and is readable
+ try {
+ fs.readdirSync(val);
+ } catch {
+ return res.status(400).json({ error: `Path not accessible: ${val}` });
+ }
+ updates.modelsFolderPath = val;
+}
+
res.json(settings.save(updates));
});