add /settings/ai route with role-aware model management
Two-tier model policy: system policy (admin, allowedModels) controls member access, per-user hiddenModels controls personal visibility. All model selectors now use useUserVisibleModels. Moved providers and model visibility out of system settings, AI models out of profile. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ export { useSettings, DEFAULT_SETTINGS } from './useSettings';
|
||||
export type { UseSettingsType, UserSettings, UserState } from './useSettings';
|
||||
export { useUserState } from './useUserState';
|
||||
export { useDashboardState } from './useDashboardState';
|
||||
export { usePiModels, useVisiblePiModels, useEnabledPiModels, modelKey } from './useModels';
|
||||
export { usePiModels, useVisiblePiModels, useUserVisibleModels, useEnabledPiModels, modelKey } from './useModels';
|
||||
export type { ModelOption } from './useModels';
|
||||
export { useAccessPolicy } from './useAccessPolicy';
|
||||
export { useRecentModels } from './useRecentModels';
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useQuery } from '@tanstack/react-query';
|
||||
import { useClient } from 'hooks/useClient';
|
||||
import { useAuth } from 'hooks/useAuth';
|
||||
import { useAccessPolicy } from './useAccessPolicy';
|
||||
import { useSettings } from './useSettings';
|
||||
import type { ModelOption } from 'officerdev';
|
||||
|
||||
export type { ModelOption };
|
||||
@@ -52,14 +53,13 @@ export function usePiModels() {
|
||||
return models;
|
||||
}
|
||||
|
||||
/** Filter models by system-wide access policy. Super Admin sees all. New providers pass through. */
|
||||
/** Filter models by system-wide access policy. New providers pass through. */
|
||||
export function useVisiblePiModels() {
|
||||
const models = usePiModels();
|
||||
const { user } = useAuth();
|
||||
const { policy } = useAccessPolicy();
|
||||
const allowed = policy.allowedModels;
|
||||
|
||||
if (user?.role === 'Super Admin' || allowed.length === 0) return models;
|
||||
if (allowed.length === 0) return models;
|
||||
|
||||
const allowedSet = new Set(allowed);
|
||||
const allowedProviderSet = new Set(allowed.map((key) => key.split(':')[0]));
|
||||
@@ -72,6 +72,23 @@ export function useVisiblePiModels() {
|
||||
});
|
||||
}
|
||||
|
||||
/** Models visible to the current user: system policy (members) or all (admins), minus per-user hidden. */
|
||||
export function useUserVisibleModels() {
|
||||
const allModels = usePiModels();
|
||||
const policyModels = useVisiblePiModels();
|
||||
const { user } = useAuth();
|
||||
const { settings } = useSettings();
|
||||
|
||||
const isAdmin = user?.role !== 'Member';
|
||||
const base = isAdmin ? allModels : policyModels;
|
||||
const hidden = settings.chat.hiddenModels;
|
||||
|
||||
if (!hidden || hidden.length === 0) return base;
|
||||
|
||||
const hiddenSet = new Set(hidden);
|
||||
return base.filter((m) => !hiddenSet.has(modelKey(m)));
|
||||
}
|
||||
|
||||
/** Strict filtering — only explicitly allowed models, no "new provider" passthrough. */
|
||||
export function useEnabledPiModels() {
|
||||
const models = usePiModels();
|
||||
|
||||
@@ -55,6 +55,7 @@ export type UserSettings = {
|
||||
systemPrompt: string;
|
||||
temperature: number;
|
||||
defaultPwd: string;
|
||||
hiddenModels?: string[];
|
||||
};
|
||||
ai: {
|
||||
enabledModels: string[];
|
||||
|
||||
Reference in New Issue
Block a user