only enabled ai models for all users

This commit is contained in:
2026-02-23 08:23:40 +00:00
parent e25f685b70
commit 7298ee72aa
5 changed files with 59 additions and 47 deletions
+2 -1
View File
@@ -2,8 +2,9 @@ export { useSettings, DEFAULT_SETTINGS } from './useSettings';
export type { UseSettingsType, UserSettings, UserState } from './useSettings';
export { useUserState } from './useUserState';
export { useWorkspacesState } from './useWorkspacesState';
export { usePiModels, useVisiblePiModels, modelKey } from './useModels';
export { usePiModels, useVisiblePiModels, useEnabledPiModels, modelKey } from './useModels';
export type { ModelOption } from './useModels';
export { useAccessPolicy } from './useAccessPolicy';
export { useRecentModels } from './useRecentModels';
export { usePlans } from './usePlans';
export { useLandingPage } from './useLandingPage';
@@ -0,0 +1,33 @@
import { useCallback } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useClient } from 'hooks/useClient';
import { useAuth } from 'hooks/useAuth';
type AccessPolicy = {
allowedModels: string[];
};
const QUERY_KEY = ['ACCESS_POLICY'];
export function useAccessPolicy() {
const client = useClient();
const { isAuthenticated } = useAuth();
const queryClient = useQueryClient();
const { data: policy = { allowedModels: [] } } = useQuery<AccessPolicy>({
queryKey: QUERY_KEY,
enabled: isAuthenticated,
queryFn: () => client.get<AccessPolicy>('/server-settings/pi-mono/access-policy'),
staleTime: 5 * 60 * 1000,
});
const savePolicy = useCallback(
async (newPolicy: AccessPolicy) => {
queryClient.setQueryData(QUERY_KEY, newPolicy);
await client.put('/server-settings/pi-mono/access-policy', newPolicy);
},
[client, queryClient],
);
return { policy, savePolicy };
}
+17 -38
View File
@@ -1,7 +1,7 @@
import { useQuery } from '@tanstack/react-query';
import { useClient } from 'hooks/useClient';
import { useAuth } from 'hooks/useAuth';
import { useSettings } from './useSettings';
import { useAccessPolicy } from './useAccessPolicy';
import type { ModelOption } from 'officerdev';
export type { ModelOption };
@@ -48,53 +48,32 @@ export function usePiModels() {
return models;
}
/** Filter models by system-wide access policy. New providers pass through. */
export function useVisiblePiModels() {
const models = usePiModels();
const { settings } = useSettings();
const enabled = settings.ai?.enabledModels ?? [];
const disabledProviders = new Set(settings.ai?.disabledProviders ?? []);
const { policy } = useAccessPolicy();
const allowed = policy.allowedModels;
// First filter out disabled providers
const providerFiltered = disabledProviders.size > 0
? models.filter((m) => !disabledProviders.has(m.provider))
: models;
if (allowed.length === 0) return models;
// If no enabled models list, show all (after provider filtering)
if (enabled.length === 0) {
return providerFiltered;
}
const allowedSet = new Set(allowed);
const allowedProviderSet = new Set(allowed.map((key) => key.split(':')[0]));
// Get all providers from enabled models
const enabledProviderSet = new Set(
enabled.map(key => key.split(':')[0]),
);
// Filter to include:
// 1. Models that are explicitly enabled
// 2. Models from providers that aren't in the enabled list at all (new providers)
return providerFiltered.filter((m) => {
const isExplicitlyEnabled = enabled.includes(modelKey(m));
const isFromNewProvider = !enabledProviderSet.has(m.provider);
return isExplicitlyEnabled || isFromNewProvider;
return models.filter((m) => {
const isExplicitlyAllowed = allowedSet.has(modelKey(m));
const isFromNewProvider = !allowedProviderSet.has(m.provider);
return isExplicitlyAllowed || isFromNewProvider;
});
}
/** Strict filtering — only explicitly enabled models, no "new provider" passthrough. */
/** Strict filtering — only explicitly allowed models, no "new provider" passthrough. */
export function useEnabledPiModels() {
const models = usePiModels();
const { settings } = useSettings();
const enabled = settings.ai?.enabledModels ?? [];
const disabledProviders = new Set(settings.ai?.disabledProviders ?? []);
const { policy } = useAccessPolicy();
const allowed = policy.allowedModels;
const providerFiltered = disabledProviders.size > 0
? models.filter((m) => !disabledProviders.has(m.provider))
: models;
if (allowed.length === 0) return models;
if (enabled.length === 0) return providerFiltered;
// Match by modelKey (new format), model id, or model name (legacy formats)
const enabledSet = new Set(enabled);
return providerFiltered.filter((m) =>
enabledSet.has(modelKey(m)) || enabledSet.has(m.id) || enabledSet.has(m.name),
);
const allowedSet = new Set(allowed);
return models.filter((m) => allowedSet.has(modelKey(m)));
}