feat(engine): 添加MCP连接管理和工具集成功能
- 集成MCP连接管理器,支持MCP服务器连接 - 添加多种内置工具:ClarifyTool、CronTool、DelegateTool、ExecuteCodeTool、 PatchFileTool、ProcessTool、SendMessageTool、SpawnTool、TerminalTool、 TodoTool、WebFetchTool、WebSearchTool、WriteFileTool等 - 实现工具注册和装配功能 - 添加技能选择上下文参数 - 支持思考模式控制参数thinking_enabled feat(coordinator): 重构任务执行计划器参数命名 - 将learning_candidate_enabled重命名为allow_candidate_generation - 更新TeamGraphScheduler中的参数传递 - 修改LocalAgentRunner中的相关参数处理 - 更新README文档中的相应描述 refactor(context): 标准化工具调用参数格式 - 添加_json导入用于参数序列化 - 实现_provider_tool_calls方法标准化OpenAI兼容的工具调用载荷 - 修复工具调用中参数非字符串类型的序列化问题 refactor(session): 优化消息历史记录过滤逻辑 - 修改get_messages_as_conversation为基于运行状态过滤消息 - 排除未完成、失败或错误结束的运行记录 - 改进对话历史的可见性控制机制 fix(store): 修复FTS索引重建逻辑 - 添加异常处理防止FTS索引创建失败 - 实现_rebuild_fts_index方法重新构建全文搜索索引 - 优化索引触发器和表的维护流程
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import {
|
||||
CheckCircle2,
|
||||
XCircle,
|
||||
@ -12,6 +13,7 @@ import {
|
||||
Key,
|
||||
Loader2,
|
||||
Settings2,
|
||||
ScrollText,
|
||||
} from 'lucide-react';
|
||||
import { getStatus, restartSystem, updateProviderConfig } from '@/lib/api';
|
||||
import {
|
||||
@ -189,65 +191,116 @@ export default function StatusPage() {
|
||||
|
||||
if (!status) return null;
|
||||
|
||||
const settingsLinks = [
|
||||
{
|
||||
href: '/logs',
|
||||
icon: ScrollText,
|
||||
title: pickAppText(locale, '运行日志', 'Runtime Logs'),
|
||||
description: pickAppText(locale, '查看每次对话和后台任务的运行日志。', 'Inspect chat and background runtime logs.'),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto p-6 space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<h1 className="text-2xl font-bold">{pickAppText(locale, '系统状态', 'System status')}</h1>
|
||||
<div className="mx-auto max-w-6xl p-6 space-y-6">
|
||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold">{pickAppText(locale, '配置', 'Settings')}</h1>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
{pickAppText(
|
||||
locale,
|
||||
'集中管理模型、工具、集成和实例运行状态。Task 和通知只在各自页面处理。',
|
||||
'Manage models, tools, integrations, and instance runtime status. Tasks and notifications stay in their own pages.'
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<Button onClick={loadStatus} variant="outline" size="sm" disabled={restarting}>
|
||||
<RefreshCw className="w-4 h-4 mr-2" />
|
||||
{pickAppText(locale, '刷新', 'Refresh')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
|
||||
{settingsLinks.map((item) => {
|
||||
const Icon = item.icon;
|
||||
return (
|
||||
<Link
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
className="group flex min-h-[116px] items-start gap-4 rounded-lg border border-border bg-background p-4 transition-colors hover:border-primary/50 hover:bg-muted/40"
|
||||
>
|
||||
<span className="mt-0.5 rounded-md border border-border bg-muted p-2 text-muted-foreground group-hover:text-primary">
|
||||
<Icon className="h-4 w-4" />
|
||||
</span>
|
||||
<span className="min-w-0 space-y-1">
|
||||
<span className="block text-sm font-semibold text-foreground">{item.title}</span>
|
||||
<span className="block text-sm leading-6 text-muted-foreground">{item.description}</span>
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* System Info */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-base">
|
||||
<Server className="w-4 h-4" />
|
||||
{pickAppText(locale, '系统信息', 'System information')}
|
||||
{pickAppText(locale, '实例运行', 'Instance runtime')}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div className="grid gap-5 lg:grid-cols-[1fr_auto] lg:items-center">
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm font-medium">{pickAppText(locale, '重启当前实例', 'Restart current instance')}</p>
|
||||
<p className="text-sm font-medium">{pickAppText(locale, '运行与调试', 'Runtime and debugging')}</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{restarting
|
||||
? pickAppText(locale, '正在重启当前 docker,服务恢复后页面会自动刷新。', 'Restarting the current Docker container. The page will refresh automatically once the service is back.')
|
||||
: pickAppText(locale, '会重启当前 docker 容器。重启完成后需要重新登录。', 'This restarts the current Docker container. You will need to sign in again afterwards.')}
|
||||
: pickAppText(locale, '查看每次对话的运行日志,或重启当前 docker 容器。重启完成后需要重新登录。', 'Inspect per-chat runtime logs or restart the current Docker container. You will need to sign in again afterwards.')}
|
||||
</p>
|
||||
{restartError ? (
|
||||
<p className="text-sm text-destructive">{restartError}</p>
|
||||
) : null}
|
||||
</div>
|
||||
<AlertDialog open={restartDialogOpen} onOpenChange={setRestartDialogOpen}>
|
||||
<Button
|
||||
variant="destructive"
|
||||
onClick={() => setRestartDialogOpen(true)}
|
||||
disabled={restarting}
|
||||
>
|
||||
{restarting ? (
|
||||
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
||||
) : (
|
||||
<RefreshCw className="w-4 h-4 mr-2" />
|
||||
)}
|
||||
Restart
|
||||
<div className="flex flex-wrap justify-start gap-2 lg:justify-end">
|
||||
<Button asChild variant="outline">
|
||||
<Link href="/logs">
|
||||
<ScrollText className="w-4 h-4 mr-2" />
|
||||
{pickAppText(locale, '运行日志', 'Runtime Logs')}
|
||||
</Link>
|
||||
</Button>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{pickAppText(locale, '确认重启当前实例?', 'Restart the current instance?')}</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{pickAppText(locale, '这会重启当前 docker 容器,页面会短暂不可用。由于当前登录态保存在内存里,重启完成后需要重新登录。', 'This restarts the current Docker container and the page will be temporarily unavailable. Because the current sign-in state is stored in memory, you will need to sign in again after the restart.')}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel disabled={restarting}>{pickAppText(locale, '取消', 'Cancel')}</AlertDialogCancel>
|
||||
<AlertDialogAction onClick={handleRestart} disabled={restarting}>
|
||||
{restarting ? pickAppText(locale, '重启中...', 'Restarting...') : pickAppText(locale, '确认重启', 'Confirm restart')}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
<AlertDialog open={restartDialogOpen} onOpenChange={setRestartDialogOpen}>
|
||||
<Button
|
||||
variant="destructive"
|
||||
onClick={() => setRestartDialogOpen(true)}
|
||||
disabled={restarting}
|
||||
>
|
||||
{restarting ? (
|
||||
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
||||
) : (
|
||||
<RefreshCw className="w-4 h-4 mr-2" />
|
||||
)}
|
||||
Restart
|
||||
</Button>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{pickAppText(locale, '确认重启当前实例?', 'Restart the current instance?')}</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{pickAppText(locale, '这会重启当前 docker 容器,页面会短暂不可用。由于当前登录态保存在内存里,重启完成后需要重新登录。', 'This restarts the current Docker container and the page will be temporarily unavailable. Because the current sign-in state is stored in memory, you will need to sign in again after the restart.')}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel disabled={restarting}>{pickAppText(locale, '取消', 'Cancel')}</AlertDialogCancel>
|
||||
<AlertDialogAction onClick={handleRestart} disabled={restarting}>
|
||||
{restarting ? pickAppText(locale, '重启中...', 'Restarting...') : pickAppText(locale, '确认重启', 'Confirm restart')}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 grid gap-3 border-t pt-5 md:grid-cols-2">
|
||||
<InfoRow label={pickAppText(locale, '配置文件', 'Config file')} value={status.config_path} />
|
||||
<InfoRow label={pickAppText(locale, '工作区', 'Workspace')} value={status.workspace} />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@ -436,23 +489,6 @@ export default function StatusPage() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Cron Summary */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-base">
|
||||
<AlertCircle className="w-4 h-4" />
|
||||
{pickAppText(locale, '调度器', 'Scheduler')}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<InfoRow
|
||||
label={pickAppText(locale, '状态', 'Status')}
|
||||
value={status.cron.enabled ? pickAppText(locale, '运行中', 'Running') : pickAppText(locale, '已停止', 'Stopped')}
|
||||
ok={status.cron.enabled}
|
||||
/>
|
||||
<InfoRow label={pickAppText(locale, '任务数', 'Jobs')} value={String(status.cron.jobs)} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user