import { useCallback, useRef, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { cloudAgentsApi } from '@/lib/cloud-agents-api'; import type { CloudChild, CloudMcp, CloudMcpInput, CloudPersonalResources, CloudSkillDraft } from '../../../shared/cloud-agents'; import { usePendingCloudInput } from './CloudPending'; export function CloudResources({ onChanged }: { onChanged: () => void }) { const [data, setData] = useState(null); const [mcp, setMcp] = useState(null); const [child, setChild] = useState(null); const [skill, setSkill] = useState(null); const [deleting, setDeleting] = useState<{ kind: 'mcp' | 'skill'; slug: string; name: string } | null>(null); const [busy, setBusy] = useState(false); const [error, setError] = useState(''); usePendingCloudInput(busy || Boolean(skill)); const refresh = useCallback(async () => setData(await cloudAgentsApi.call('resources', {})), []); const act = async (action: () => Promise) => { setBusy(true); setError(''); try { await action(); await refresh(); onChanged(); } catch (e) { setError(e instanceof Error ? e.message : '能力管理失败'); } finally { setBusy(false); } }; return
{ if (e.currentTarget.open && !data) void act(refresh); }}> 管理我的云端能力

连接、Skills 和子智能体属于你的个人账号。创建后在上面的能力目录选用,保存并发布后生效。

{error &&

{error}

}

MCP 连接

连接由云端访问。凭据只用于你的连接,分享调用可在你已发布的授权范围内使用这些工具。

{mcp && setMcp(null)} onSaved={() => { setMcp(null); void act(refresh); }} />} {data?.mcps.map(item =>

{item.name} · {item.enabled ? '已启用' : '已停用'} · {item.has_credentials ? '已配置凭据' : '无凭据'}

{item.url}

)}

个人 Skills

支持 SKILL.md 或单个 Skill 的 ZIP,最大 5 MB。同名 Skill 需先删除个人旧版再安装,并重新核对相关智能体配置。

{skill &&
{skill.items.map(item =>

{item.name || item.slug} · {item.description}{item.error && {item.error}}

)}
} {data?.skills.map(item =>

{item.name}

{item.description}

)}

个人子智能体

子智能体处理专门任务,继承父智能体发布的模型、能力和费用限制。

{child && setChild(null)} onSaved={() => { setChild(null); void act(refresh); }} />} {data?.subagents.map(item =>

{item.name}

{item.purpose}

)}
{deleting &&

删除“{deleting.name}”?其他智能体中选用的此项能力也会不可用,请同步调整配置。

}
; } function McpEditor({ initial, onClose, onSaved }: { initial?: CloudMcp; onClose: () => void; onSaved: () => void }) { const [value, setValue] = useState(initial ?? { name: '', description: '', url: '', transport: 'streamable_http' }); const [token, setToken] = useState(''); const [clear, setClear] = useState(false); const [busy, setBusy] = useState(false); const [error, setError] = useState(''); const [intent, setIntent] = useState<(CloudMcpInput & { operation_id: string }) | null>(null); usePendingCloudInput(busy || Boolean(intent) || Boolean(token) || clear || value.name !== (initial?.name ?? '') || value.url !== (initial?.url ?? '') || value.description !== (initial?.description ?? '') || value.transport !== (initial?.transport ?? 'streamable_http')); return
{initial?.has_credentials && }
{error &&

{error}。可重试原操作,或返回能力列表核对。

}
; } function ChildEditor({ initial, onClose, onSaved }: { initial?: CloudChild; onClose: () => void; onSaved: () => void }) { const [value, setValue] = useState>(initial ?? { name: '', purpose: '', system_prompt: '' }); const [busy, setBusy] = useState(false); const [error, setError] = useState(''); const operation = useRef(null); usePendingCloudInput(busy || Boolean(operation.current) || value.name !== (initial?.name ?? '') || value.purpose !== (initial?.purpose ?? '') || value.system_prompt !== (initial?.system_prompt ?? '')); return