refactor(agent): 将 Summary Model 改造为内置 Sub Agent
- 扩展 AgentMode 类型添加 'internal' 模式 - 新增 summary agent preset (claude-3-5-haiku) - AgentRegistry 添加 getInternal/listInternalAgents 方法 - CompressionManager 添加 setSummaryModelFromAgentConfig - Agent 构造函数改用 Registry 配置初始化 Summary 模型 - 清理旧的 SummaryConfig 配置系统 - UI AgentsPanel 分离显示 System/Preset/Custom agents - UI AgentEditor 为 internal agent 显示简化编辑界面
This commit is contained in:
@@ -20,6 +20,7 @@ import {
|
||||
Sparkles,
|
||||
Cpu,
|
||||
Layers,
|
||||
Lock,
|
||||
} from 'lucide-react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { toast } from 'sonner';
|
||||
@@ -52,6 +53,8 @@ function getModeColor(mode: AgentListItem['mode']) {
|
||||
return 'bg-purple-500/20 text-purple-400';
|
||||
case 'all':
|
||||
return 'bg-green-500/20 text-green-400';
|
||||
case 'internal':
|
||||
return 'bg-slate-500/20 text-slate-400';
|
||||
default:
|
||||
return 'bg-gray-500/20 text-gray-400';
|
||||
}
|
||||
@@ -66,6 +69,8 @@ function getModeText(mode: AgentListItem['mode']) {
|
||||
return 'Subagent';
|
||||
case 'all':
|
||||
return 'Both';
|
||||
case 'internal':
|
||||
return 'Internal';
|
||||
default:
|
||||
return mode;
|
||||
}
|
||||
@@ -189,9 +194,10 @@ export function AgentsPanel({ onClose, responsive = false }: AgentsPanelProps) {
|
||||
setAgentDetails({});
|
||||
};
|
||||
|
||||
// 统计
|
||||
const presetAgents = agents.filter((a) => a.isPreset);
|
||||
const customAgents = agents.filter((a) => !a.isPreset);
|
||||
// 统计 - 按分类过滤
|
||||
const internalAgents = agents.filter((a) => a.mode === 'internal');
|
||||
const presetAgents = agents.filter((a) => a.isPreset && a.mode !== 'internal');
|
||||
const customAgents = agents.filter((a) => !a.isPreset && a.mode !== 'internal');
|
||||
|
||||
// Loading 骨架屏
|
||||
const LoadingSkeleton = () => (
|
||||
@@ -214,6 +220,7 @@ export function AgentsPanel({ onClose, responsive = false }: AgentsPanelProps) {
|
||||
const isExpanded = expandedAgents.has(agent.name);
|
||||
const isLoading = actionLoading === agent.name;
|
||||
const detail = agentDetails[agent.name];
|
||||
const isInternal = agent.mode === 'internal';
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
@@ -236,7 +243,9 @@ export function AgentsPanel({ onClose, responsive = false }: AgentsPanelProps) {
|
||||
</button>
|
||||
|
||||
{/* Icon */}
|
||||
{agent.isPreset ? (
|
||||
{isInternal ? (
|
||||
<Lock size={16} className="text-slate-400" />
|
||||
) : agent.isPreset ? (
|
||||
<Sparkles size={16} className="text-yellow-400" />
|
||||
) : (
|
||||
<Bot size={16} className="text-primary-400" />
|
||||
@@ -264,8 +273,18 @@ export function AgentsPanel({ onClose, responsive = false }: AgentsPanelProps) {
|
||||
<div className="animate-spin rounded-full h-5 w-5 border-t-2 border-b-2 border-primary-500" />
|
||||
) : (
|
||||
<>
|
||||
{/* View/Edit */}
|
||||
{agent.isPreset && !agent.isCustomized ? (
|
||||
{/* View/Edit - Internal agents can be edited (model config) */}
|
||||
{isInternal ? (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setEditingAgent({ name: agent.name, isNew: false })}
|
||||
className="text-blue-400 hover:text-blue-300"
|
||||
title="Edit Model Config"
|
||||
>
|
||||
<Edit3 size={14} />
|
||||
</Button>
|
||||
) : agent.isPreset && !agent.isCustomized ? (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
@@ -287,19 +306,21 @@ export function AgentsPanel({ onClose, responsive = false }: AgentsPanelProps) {
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/* Copy */}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleCopy(agent.name)}
|
||||
className="text-gray-400 hover:text-gray-300"
|
||||
title="Copy"
|
||||
>
|
||||
<Copy size={14} />
|
||||
</Button>
|
||||
{/* Copy - not for internal agents */}
|
||||
{!isInternal && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleCopy(agent.name)}
|
||||
className="text-gray-400 hover:text-gray-300"
|
||||
title="Copy"
|
||||
>
|
||||
<Copy size={14} />
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/* Delete (only for custom agents) */}
|
||||
{!agent.isPreset && (
|
||||
{/* Delete (only for custom agents, not internal) */}
|
||||
{!agent.isPreset && !isInternal && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
@@ -475,7 +496,7 @@ export function AgentsPanel({ onClose, responsive = false }: AgentsPanelProps) {
|
||||
Agent Presets
|
||||
</h2>
|
||||
<p className="text-xs text-gray-500">
|
||||
{agents.length} agents ({presetAgents.length} preset, {customAgents.length} custom)
|
||||
{agents.length} agents ({internalAgents.length} system, {presetAgents.length} preset, {customAgents.length} custom)
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -541,6 +562,21 @@ export function AgentsPanel({ onClose, responsive = false }: AgentsPanelProps) {
|
||||
animate={{ opacity: 1 }}
|
||||
className={cn('space-y-4', responsive ? 'p-4' : 'p-4')}
|
||||
>
|
||||
{/* System Agents (Internal) */}
|
||||
{internalAgents.length > 0 && (
|
||||
<div>
|
||||
<h3 className="text-xs font-medium text-slate-400 uppercase tracking-wide mb-2 flex items-center gap-2">
|
||||
<Lock size={12} />
|
||||
System Agents
|
||||
</h3>
|
||||
<div className="space-y-2">
|
||||
{internalAgents.map((agent) => (
|
||||
<AgentItem key={agent.name} agent={agent} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Preset Agents */}
|
||||
{presetAgents.length > 0 && (
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user