mirror of
https://github.com/nocobase/nocobase.git
synced 2026-10-30 18:42:22 +08:00
fix(ai): enabled employees & model configure & chat button (#8650)
* fix(ai): enabled employees & model configure & chat button * fix: permission table
This commit is contained in:
@@ -13,12 +13,14 @@ import { useField } from '@formily/react';
|
||||
import { Field } from '@formily/core';
|
||||
import { useCollectionRecordData, useDataBlockRequest, useDataBlockResource } from '@nocobase/client';
|
||||
import { useT } from '../../locale';
|
||||
import { useAIEmployeesData } from '../hooks/useAIEmployeesData';
|
||||
|
||||
export const EnableSwitch: React.FC = () => {
|
||||
const field = useField<Field>();
|
||||
const record = useCollectionRecordData();
|
||||
const resource = useDataBlockResource();
|
||||
const { refresh } = useDataBlockRequest();
|
||||
const { refresh: refreshAIEmployees } = useAIEmployeesData();
|
||||
const { message } = App.useApp();
|
||||
const t = useT();
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -32,6 +34,7 @@ export const EnableSwitch: React.FC = () => {
|
||||
});
|
||||
message.success(t('Saved successfully'));
|
||||
refresh();
|
||||
refreshAIEmployees();
|
||||
} catch (error) {
|
||||
message.error(t('Failed to update'));
|
||||
} finally {
|
||||
|
||||
@@ -23,7 +23,7 @@ import { useChatConversationsStore } from './stores/chat-conversations';
|
||||
export const ChatButton: React.FC = observer(() => {
|
||||
const ctx = useFlowContext<FlowRuntimeContext>();
|
||||
const { isMobileLayout } = useMobileLayout();
|
||||
const isV2Page = ctx.pageInfo.version === 'v2';
|
||||
const isV1Page = ctx?.pageInfo?.version === 'v1';
|
||||
const { token } = useToken();
|
||||
|
||||
const { aiEmployees } = useAIEmployeesData();
|
||||
@@ -56,15 +56,14 @@ export const ChatButton: React.FC = observer(() => {
|
||||
}));
|
||||
}, [aiEmployees]);
|
||||
|
||||
if (open || !aiEmployees?.length) {
|
||||
if (open || !aiEmployees?.length || isV1Page) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const buttonShadow = token.boxShadowSecondary || token.boxShadow;
|
||||
|
||||
return (
|
||||
!isMobileLayout &&
|
||||
isV2Page && (
|
||||
!isMobileLayout && (
|
||||
<Dropdown
|
||||
menu={{ items }}
|
||||
placement="topRight"
|
||||
|
||||
-5
@@ -128,11 +128,6 @@ export const Permissions: React.FC<{
|
||||
dataIndex: 'position',
|
||||
title: t('Position'),
|
||||
},
|
||||
{
|
||||
dataIndex: 'modelSettings',
|
||||
title: t('Model'),
|
||||
render: (value) => value?.model && <Tag>{value?.model}</Tag>,
|
||||
},
|
||||
{
|
||||
dataIndex: 'available',
|
||||
title: (
|
||||
|
||||
+25
-11
@@ -112,6 +112,7 @@ export const EnabledModelsSelect: React.FC<any> = observer((props) => {
|
||||
// Use provider-specific formatModelLabel if available, otherwise default
|
||||
const providerOptions = provider ? plugin.aiManager.llmProviders.get(provider) : null;
|
||||
const labelFormatter = providerOptions?.formatModelLabel || formatModelLabel;
|
||||
const hasRecommended = !!provider && getRecommendedModels(provider).length > 0;
|
||||
|
||||
// Access deep properties to establish observer tracking
|
||||
const optionsKey = JSON.stringify(formOptions);
|
||||
@@ -136,6 +137,17 @@ export const EnabledModelsSelect: React.FC<any> = observer((props) => {
|
||||
modelsCache.current[normalized.mode] = normalized.models;
|
||||
}, []);
|
||||
|
||||
// If there are no recommended models, default to provider mode.
|
||||
useEffect(() => {
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
if (!hasRecommended && config.mode === 'recommended') {
|
||||
modelsCache.current.recommended = config.models;
|
||||
updateFieldValue({ mode: 'provider', models: modelsCache.current.provider || [] });
|
||||
}
|
||||
}, [provider, hasRecommended, config.mode]);
|
||||
|
||||
// Reset options when provider or options change so stale data is cleared
|
||||
const prevKeyRef = useRef<string>('');
|
||||
useEffect(() => {
|
||||
@@ -226,17 +238,19 @@ export const EnabledModelsSelect: React.FC<any> = observer((props) => {
|
||||
<div style={{ width: '100%' }}>
|
||||
<Radio.Group value={config.mode} onChange={(e) => handleModeChange(e.target.value)} style={{ width: '100%' }}>
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Radio value="recommended">{t('Recommended models')}</Radio>
|
||||
{config.mode === 'recommended' && (
|
||||
<Text type="secondary" style={{ paddingLeft: 24 }}>
|
||||
{t('Use recommended models:')}
|
||||
{provider &&
|
||||
getRecommendedModels(provider).length > 0 &&
|
||||
' ' +
|
||||
getRecommendedModels(provider)
|
||||
.map((m) => m.label)
|
||||
.join(', ')}
|
||||
</Text>
|
||||
{hasRecommended && (
|
||||
<>
|
||||
<Radio value="recommended">{t('Recommended models')}</Radio>
|
||||
{config.mode === 'recommended' && (
|
||||
<Text type="secondary" style={{ paddingLeft: 24 }}>
|
||||
{t('Use recommended models:') +
|
||||
' ' +
|
||||
getRecommendedModels(provider)
|
||||
.map((m) => m.label)
|
||||
.join(', ')}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
<Radio value="provider">{t('Select models')}</Radio>
|
||||
|
||||
+2
-2
@@ -38,14 +38,14 @@ export const LLMTestFlight: React.FC = observer(() => {
|
||||
if (config.mode === 'recommended') {
|
||||
const recommended = getRecommendedModels(provider);
|
||||
if (recommended.length === 0) {
|
||||
message.warning(t('Please set up Enabled Models first'));
|
||||
message.warning(t('Please configure enabled models first'));
|
||||
return;
|
||||
}
|
||||
model = recommended[0].value;
|
||||
} else {
|
||||
// provider or custom mode
|
||||
if (config.models.length === 0) {
|
||||
message.warning(t('Please set up Enabled Models first'));
|
||||
message.warning(t('Please configure enabled models first'));
|
||||
return;
|
||||
}
|
||||
model = config.models[0].value;
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
"Recommended": "Recommended",
|
||||
"Select models to enable": "Select models to enable",
|
||||
"Please fill in the API Key first": "Please fill in the API Key first",
|
||||
"Please set up Enabled Models first": "Please set up Enabled Models first",
|
||||
"Please configure enabled models first": "Please configure enabled models first",
|
||||
"Test connection with the configured API Key": "Test connection with the configured API Key",
|
||||
"Successful": "Successful",
|
||||
"Failure": "Failure",
|
||||
|
||||
@@ -260,7 +260,7 @@
|
||||
"Recommended": "推荐",
|
||||
"Select models to enable": "选择要启用的模型",
|
||||
"Please fill in the API Key first": "请先填写 API Key",
|
||||
"Please set up Enabled Models first": "请先设置 Enabled Models",
|
||||
"Please configure enabled models first": "请先配置启用的模型",
|
||||
"Test connection with the configured API Key": "测试配置的 API Key 连接",
|
||||
"Successful": "成功",
|
||||
"Failure": "失败",
|
||||
|
||||
@@ -108,7 +108,7 @@ export class BuiltInManager {
|
||||
enableKnowledgeBase: false,
|
||||
knowledgeBase: DEFAULT_KNOWLEDGE_BASE,
|
||||
knowledgeBasePrompt: DEFAULT_KNOWLEDGE_BASE_PROMPT,
|
||||
enabled: false,
|
||||
enabled: true,
|
||||
builtIn: true,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user