Skip to content

Commit 7f144c9

Browse files
committed
move fine-tune to generic features
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
1 parent 8784646 commit 7f144c9

4 files changed

Lines changed: 52 additions & 7 deletions

File tree

core/http/auth/features.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ func AgentFeatureMetas() []FeatureMeta {
113113
{FeatureSkills, "Skills", false},
114114
{FeatureCollections, "Collections", false},
115115
{FeatureMCPJobs, "MCP CI Jobs", false},
116+
}
117+
}
118+
119+
// GeneralFeatureMetas returns metadata for general features.
120+
func GeneralFeatureMetas() []FeatureMeta {
121+
return []FeatureMeta{
116122
{FeatureFineTuning, "Fine-Tuning", false},
117123
}
118124
}

core/http/auth/permissions.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ const (
3131
FeatureSkills = "skills"
3232
FeatureCollections = "collections"
3333
FeatureMCPJobs = "mcp_jobs"
34-
FeatureFineTuning = "fine_tuning"
34+
35+
// General features (default OFF for new users)
36+
FeatureFineTuning = "fine_tuning"
3537

3638
// API features (default ON for new users)
3739
FeatureChat = "chat"
@@ -51,7 +53,10 @@ const (
5153
)
5254

5355
// AgentFeatures lists agent-related features (default OFF).
54-
var AgentFeatures = []string{FeatureAgents, FeatureSkills, FeatureCollections, FeatureMCPJobs, FeatureFineTuning}
56+
var AgentFeatures = []string{FeatureAgents, FeatureSkills, FeatureCollections, FeatureMCPJobs}
57+
58+
// GeneralFeatures lists general features (default OFF).
59+
var GeneralFeatures = []string{FeatureFineTuning}
5560

5661
// APIFeatures lists API endpoint features (default ON).
5762
var APIFeatures = []string{
@@ -61,7 +66,7 @@ var APIFeatures = []string{
6166
}
6267

6368
// AllFeatures lists all known features (used by UI and validation).
64-
var AllFeatures = append(append([]string{}, AgentFeatures...), APIFeatures...)
69+
var AllFeatures = append(append(append([]string{}, AgentFeatures...), GeneralFeatures...), APIFeatures...)
6570

6671
// defaultOnFeatures is the set of features that default to ON when absent from a user's permission map.
6772
var defaultOnFeatures = func() map[string]bool {

core/http/react-ui/src/pages/Users.jsx

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ function PermissionSummary({ user, onClick }) {
4545
const perms = user.permissions || {}
4646
const apiFeatures = ['chat', 'images', 'audio_speech', 'audio_transcription', 'vad', 'detection', 'video', 'embeddings', 'sound']
4747
const agentFeatures = ['agents', 'skills', 'collections', 'mcp_jobs']
48+
const generalFeatures = ['fine_tuning']
4849

4950
const apiOn = apiFeatures.filter(f => perms[f] !== false && (perms[f] === true || perms[f] === undefined)).length
5051
const agentOn = agentFeatures.filter(f => perms[f]).length
52+
const generalOn = generalFeatures.filter(f => perms[f]).length
5153

5254
const modelRestricted = user.allowed_models?.enabled
5355

@@ -58,7 +60,7 @@ function PermissionSummary({ user, onClick }) {
5860
title="Edit permissions"
5961
>
6062
<i className="fas fa-shield-halved" />
61-
{apiOn}/{apiFeatures.length} API, {agentOn}/{agentFeatures.length} Agent
63+
{apiOn}/{apiFeatures.length} API, {agentOn}/{agentFeatures.length} Agent, {generalOn}/{generalFeatures.length} Features
6264
{modelRestricted && ' | Models restricted'}
6365
</button>
6466
)
@@ -71,6 +73,7 @@ function PermissionsModal({ user, featureMeta, availableModels, onClose, onSave,
7173

7274
const apiFeatures = featureMeta?.api_features || []
7375
const agentFeatures = featureMeta?.agent_features || []
76+
const generalFeatures = featureMeta?.general_features || []
7477

7578
useEffect(() => {
7679
const handleKeyDown = (e) => {
@@ -189,6 +192,33 @@ function PermissionsModal({ user, featureMeta, availableModels, onClose, onSave,
189192
</div>
190193
</div>
191194

195+
{/* General Features */}
196+
{generalFeatures.length > 0 && (
197+
<div className="perm-section">
198+
<div className="perm-section-header">
199+
<strong className="perm-section-title">
200+
<i className="fas fa-sliders" />
201+
Features
202+
</strong>
203+
<div className="action-group">
204+
<button className="btn btn-sm btn-secondary perm-btn-all-none" onClick={() => setAllFeatures(generalFeatures, true)}>All</button>
205+
<button className="btn btn-sm btn-secondary perm-btn-all-none" onClick={() => setAllFeatures(generalFeatures, false)}>None</button>
206+
</div>
207+
</div>
208+
<div className="perm-grid">
209+
{generalFeatures.map(f => (
210+
<button
211+
key={f.key}
212+
className={`btn btn-sm ${permissions[f.key] ? 'btn-primary' : 'btn-secondary'} perm-btn-feature`}
213+
onClick={() => toggleFeature(f.key)}
214+
>
215+
{f.label}
216+
</button>
217+
))}
218+
</div>
219+
</div>
220+
)}
221+
192222
{/* Model Access */}
193223
<div className="perm-section">
194224
<div className="perm-section-header">
@@ -510,6 +540,9 @@ export default function Users() {
510540
{ key: 'collections', label: 'Collections', default: false },
511541
{ key: 'mcp_jobs', label: 'MCP CI Jobs', default: false },
512542
],
543+
general_features: [
544+
{ key: 'fine_tuning', label: 'Fine-Tuning', default: false },
545+
],
513546
})
514547
}
515548
}, [])

core/http/routes/auth.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -777,9 +777,10 @@ func RegisterAuthRoutes(e *echo.Echo, app *application.Application) {
777777
}
778778

779779
return c.JSON(http.StatusOK, map[string]interface{}{
780-
"agent_features": auth.AgentFeatureMetas(),
781-
"api_features": auth.APIFeatureMetas(),
782-
"models": modelNames,
780+
"agent_features": auth.AgentFeatureMetas(),
781+
"general_features": auth.GeneralFeatureMetas(),
782+
"api_features": auth.APIFeatureMetas(),
783+
"models": modelNames,
783784
})
784785
}, adminMw)
785786

0 commit comments

Comments
 (0)