Merge branch 'codex/reminder-llm-toggle'
This commit is contained in:
+22
-1
@@ -97,6 +97,7 @@ export function createAdminApp(services) {
|
|||||||
loadMindSpaceConfig,
|
loadMindSpaceConfig,
|
||||||
updateMindSpaceConfig,
|
updateMindSpaceConfig,
|
||||||
memoryV2ConfigService,
|
memoryV2ConfigService,
|
||||||
|
wechatScheduleLlmConfigService,
|
||||||
adminSystemTestService,
|
adminSystemTestService,
|
||||||
systemTestAccountService,
|
systemTestAccountService,
|
||||||
wordFilterService,
|
wordFilterService,
|
||||||
@@ -285,7 +286,27 @@ export function createAdminApp(services) {
|
|||||||
|
|
||||||
adminApi.get('/wechat/summary', requireAdmin, async (_req, res) => {
|
adminApi.get('/wechat/summary', requireAdmin, async (_req, res) => {
|
||||||
if (!wechatAdmin) return res.status(503).json({ message: '服务号管理未启用' });
|
if (!wechatAdmin) return res.status(503).json({ message: '服务号管理未启用' });
|
||||||
res.json(await wechatAdmin.getSummary());
|
const summary = await wechatAdmin.getSummary();
|
||||||
|
const scheduleLlmConfig = wechatScheduleLlmConfigService
|
||||||
|
? await wechatScheduleLlmConfigService.getConfig()
|
||||||
|
: { scheduleLlmEnabled: false };
|
||||||
|
res.json({
|
||||||
|
...summary,
|
||||||
|
config: {
|
||||||
|
...summary.config,
|
||||||
|
scheduleLlmEnabled: scheduleLlmConfig.scheduleLlmEnabled,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
adminApi.patch('/wechat/schedule-llm-config', requireAdmin, async (req, res) => {
|
||||||
|
if (!wechatScheduleLlmConfigService) {
|
||||||
|
return res.status(503).json({ message: '服务号提醒 LLM 配置未启用' });
|
||||||
|
}
|
||||||
|
const result = await wechatScheduleLlmConfigService.updateConfig(req.body ?? {}, {
|
||||||
|
updatedBy: req.currentUser.id,
|
||||||
|
});
|
||||||
|
res.json(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
adminApi.get('/mindspace/config', requireAdmin, async (_req, res) => {
|
adminApi.get('/mindspace/config', requireAdmin, async (_req, res) => {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export async function bootstrapAdminServices() {
|
|||||||
updateMindSpaceConfig,
|
updateMindSpaceConfig,
|
||||||
} = await importMemind('mindspace-config.mjs');
|
} = await importMemind('mindspace-config.mjs');
|
||||||
const { createMemoryV2AdminConfigService } = await importMemind('memory-v2-admin-config.mjs');
|
const { createMemoryV2AdminConfigService } = await importMemind('memory-v2-admin-config.mjs');
|
||||||
|
const { createWechatScheduleLlmConfigService } = await importMemind('wechat-schedule-llm-config.mjs');
|
||||||
const { createAdminSystemTestService } = await importMemind('admin-system-tests.mjs');
|
const { createAdminSystemTestService } = await importMemind('admin-system-tests.mjs');
|
||||||
const { createOpsApi } = await importMemind('admin-routes.mjs');
|
const { createOpsApi } = await importMemind('admin-routes.mjs');
|
||||||
const { createWordFilterService, ensureWordFilterSchema } = await importMemind('word-filter.mjs');
|
const { createWordFilterService, ensureWordFilterSchema } = await importMemind('word-filter.mjs');
|
||||||
@@ -88,6 +89,9 @@ export async function bootstrapAdminServices() {
|
|||||||
const memoryV2ConfigService = createMemoryV2AdminConfigService(pool, {
|
const memoryV2ConfigService = createMemoryV2AdminConfigService(pool, {
|
||||||
env: process.env,
|
env: process.env,
|
||||||
});
|
});
|
||||||
|
const wechatScheduleLlmConfigService = createWechatScheduleLlmConfigService(pool, {
|
||||||
|
env: process.env,
|
||||||
|
});
|
||||||
const adminSystemTestService = createAdminSystemTestService({
|
const adminSystemTestService = createAdminSystemTestService({
|
||||||
pool,
|
pool,
|
||||||
userAuth,
|
userAuth,
|
||||||
@@ -136,6 +140,7 @@ export async function bootstrapAdminServices() {
|
|||||||
loadMindSpaceConfig,
|
loadMindSpaceConfig,
|
||||||
updateMindSpaceConfig,
|
updateMindSpaceConfig,
|
||||||
memoryV2ConfigService,
|
memoryV2ConfigService,
|
||||||
|
wechatScheduleLlmConfigService,
|
||||||
adminSystemTestService,
|
adminSystemTestService,
|
||||||
systemTestAccountService,
|
systemTestAccountService,
|
||||||
wordFilterService,
|
wordFilterService,
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ ready
|
|||||||
loadMindSpaceConfig,
|
loadMindSpaceConfig,
|
||||||
updateMindSpaceConfig,
|
updateMindSpaceConfig,
|
||||||
memoryV2ConfigService,
|
memoryV2ConfigService,
|
||||||
|
wechatScheduleLlmConfigService,
|
||||||
adminSystemTestService,
|
adminSystemTestService,
|
||||||
systemTestAccountService,
|
systemTestAccountService,
|
||||||
wordFilterService,
|
wordFilterService,
|
||||||
@@ -125,6 +126,7 @@ ready
|
|||||||
loadMindSpaceConfig,
|
loadMindSpaceConfig,
|
||||||
updateMindSpaceConfig,
|
updateMindSpaceConfig,
|
||||||
memoryV2ConfigService,
|
memoryV2ConfigService,
|
||||||
|
wechatScheduleLlmConfigService,
|
||||||
adminSystemTestService,
|
adminSystemTestService,
|
||||||
systemTestAccountService,
|
systemTestAccountService,
|
||||||
wordFilterService,
|
wordFilterService,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
listWechatMessages,
|
listWechatMessages,
|
||||||
listWechatWebNotifications,
|
listWechatWebNotifications,
|
||||||
resumeWechatDigest,
|
resumeWechatDigest,
|
||||||
|
updateWechatScheduleLlmConfig,
|
||||||
} from '../../api/client';
|
} from '../../api/client';
|
||||||
import type {
|
import type {
|
||||||
AdminUserRow,
|
AdminUserRow,
|
||||||
@@ -38,6 +39,7 @@ function safeSummary(summary: WechatAdminSummary | null) {
|
|||||||
bindPath: null,
|
bindPath: null,
|
||||||
tokenEndpointConfigured: false,
|
tokenEndpointConfigured: false,
|
||||||
customerServiceEndpointConfigured: false,
|
customerServiceEndpointConfigured: false,
|
||||||
|
scheduleLlmEnabled: false,
|
||||||
},
|
},
|
||||||
counts: summary?.counts ?? {
|
counts: summary?.counts ?? {
|
||||||
boundUsers: 0,
|
boundUsers: 0,
|
||||||
@@ -88,6 +90,7 @@ export function WechatPage() {
|
|||||||
const [notifyBody, setNotifyBody] = useState('');
|
const [notifyBody, setNotifyBody] = useState('');
|
||||||
const [notifyType, setNotifyType] = useState('manual');
|
const [notifyType, setNotifyType] = useState('manual');
|
||||||
const [notifyChannels, setNotifyChannels] = useState<Array<'web' | 'wechat'>>(['web']);
|
const [notifyChannels, setNotifyChannels] = useState<Array<'web' | 'wechat'>>(['web']);
|
||||||
|
const [scheduleLlmEnabled, setScheduleLlmEnabled] = useState(false);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [busy, setBusy] = useState(false);
|
const [busy, setBusy] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
@@ -117,6 +120,7 @@ export function WechatPage() {
|
|||||||
listAdminUsers({ page: 1, pageSize: 200, status: 'active' }),
|
listAdminUsers({ page: 1, pageSize: 200, status: 'active' }),
|
||||||
]);
|
]);
|
||||||
setSummary(nextSummary);
|
setSummary(nextSummary);
|
||||||
|
setScheduleLlmEnabled(nextSummary.config.scheduleLlmEnabled ?? false);
|
||||||
setBindings(nextBindings);
|
setBindings(nextBindings);
|
||||||
setMessages(nextMessages);
|
setMessages(nextMessages);
|
||||||
setDigests(nextDigests);
|
setDigests(nextDigests);
|
||||||
@@ -224,6 +228,13 @@ export function WechatPage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSaveScheduleLlm = async () => {
|
||||||
|
await runAction(async () => {
|
||||||
|
await updateWechatScheduleLlmConfig({ scheduleLlmEnabled });
|
||||||
|
setNotice(`提醒待办 LLM 已${scheduleLlmEnabled ? '开启' : '关闭'}。`);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="admin-page">
|
<div className="admin-page">
|
||||||
<div className="admin-page-head">
|
<div className="admin-page-head">
|
||||||
@@ -280,7 +291,28 @@ export function WechatPage() {
|
|||||||
<dt>推送 worker</dt>
|
<dt>推送 worker</dt>
|
||||||
<dd>{summary.config.reminderWorkerEnabled ? '已启用' : '未启用'}</dd>
|
<dd>{summary.config.reminderWorkerEnabled ? '已启用' : '未启用'}</dd>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt>提醒待办 LLM</dt>
|
||||||
|
<dd>{summary.config.scheduleLlmEnabled ? '已开启' : '已关闭'}</dd>
|
||||||
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
|
<div className="wechat-toolbar" style={{ marginTop: 16, justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={scheduleLlmEnabled}
|
||||||
|
onChange={(event) => setScheduleLlmEnabled(event.target.checked)}
|
||||||
|
disabled={busy}
|
||||||
|
/>{' '}
|
||||||
|
启用提醒待办 LLM 辅助识别
|
||||||
|
</label>
|
||||||
|
<button type="button" className="ghost-btn" onClick={() => void handleSaveScheduleLlm()} disabled={busy}>
|
||||||
|
{busy ? '保存中…' : '保存开关'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p className="muted" style={{ marginTop: 8 }}>
|
||||||
|
默认关闭。开启后仅在规则未识别出提醒意图时,才调用后台已选中的 LLM 做补充解析;复杂定时提醒仍走原有会话链路。
|
||||||
|
</p>
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import type {
|
|||||||
WechatBinding,
|
WechatBinding,
|
||||||
WechatDeliveryLog,
|
WechatDeliveryLog,
|
||||||
WechatDigestSubscription,
|
WechatDigestSubscription,
|
||||||
|
WechatScheduleLlmConfig,
|
||||||
WechatMessage,
|
WechatMessage,
|
||||||
WechatWebNotification,
|
WechatWebNotification,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
@@ -254,6 +255,7 @@ export async function getWechatAdminSummary(): Promise<WechatAdminSummary> {
|
|||||||
bindPath: summary.config?.bindPath ?? null,
|
bindPath: summary.config?.bindPath ?? null,
|
||||||
tokenEndpointConfigured: summary.config?.tokenEndpointConfigured ?? false,
|
tokenEndpointConfigured: summary.config?.tokenEndpointConfigured ?? false,
|
||||||
customerServiceEndpointConfigured: summary.config?.customerServiceEndpointConfigured ?? false,
|
customerServiceEndpointConfigured: summary.config?.customerServiceEndpointConfigured ?? false,
|
||||||
|
scheduleLlmEnabled: summary.config?.scheduleLlmEnabled ?? false,
|
||||||
},
|
},
|
||||||
counts: {
|
counts: {
|
||||||
boundUsers: summary.counts?.boundUsers ?? 0,
|
boundUsers: summary.counts?.boundUsers ?? 0,
|
||||||
@@ -268,6 +270,15 @@ export async function getWechatAdminSummary(): Promise<WechatAdminSummary> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updateWechatScheduleLlmConfig(
|
||||||
|
payload: Pick<WechatScheduleLlmConfig, 'scheduleLlmEnabled'>,
|
||||||
|
): Promise<WechatScheduleLlmConfig> {
|
||||||
|
return portalFetch<WechatScheduleLlmConfig>('/admin-api/wechat/schedule-llm-config', {
|
||||||
|
method: 'PATCH',
|
||||||
|
body: JSON.stringify(payload),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function getMindSpaceAdminConfig(): Promise<MindSpaceAdminConfig> {
|
export async function getMindSpaceAdminConfig(): Promise<MindSpaceAdminConfig> {
|
||||||
const result = await portalFetch<{ config: MindSpaceAdminConfig }>('/admin-api/mindspace/config');
|
const result = await portalFetch<{ config: MindSpaceAdminConfig }>('/admin-api/mindspace/config');
|
||||||
return result.config;
|
return result.config;
|
||||||
|
|||||||
@@ -241,6 +241,7 @@ export type WechatAdminSummary = {
|
|||||||
bindPath: string | null;
|
bindPath: string | null;
|
||||||
tokenEndpointConfigured: boolean;
|
tokenEndpointConfigured: boolean;
|
||||||
customerServiceEndpointConfigured: boolean;
|
customerServiceEndpointConfigured: boolean;
|
||||||
|
scheduleLlmEnabled: boolean;
|
||||||
};
|
};
|
||||||
counts: {
|
counts: {
|
||||||
boundUsers: number;
|
boundUsers: number;
|
||||||
@@ -251,6 +252,12 @@ export type WechatAdminSummary = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type WechatScheduleLlmConfig = {
|
||||||
|
scheduleLlmEnabled: boolean;
|
||||||
|
updatedAt: number | null;
|
||||||
|
updatedBy: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
export type MindSpaceAdminConfig = {
|
export type MindSpaceAdminConfig = {
|
||||||
publicPageLimit: number;
|
publicPageLimit: number;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user