@hualinge/relay-web 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +31 -0
- package/dist/assets/AgentsPage-2u2kFBCH.js +68 -0
- package/dist/assets/AgentsPage-2u2kFBCH.js.map +1 -0
- package/dist/assets/AgentsPage-BGbbVmeL.css +1 -0
- package/dist/assets/Alert-D88Fk6to.js +2 -0
- package/dist/assets/Alert-D88Fk6to.js.map +1 -0
- package/dist/assets/AppModal-BYZTSuch.js +2 -0
- package/dist/assets/AppModal-BYZTSuch.js.map +1 -0
- package/dist/assets/CenteredLoadingState-DHor-9vF.js +2 -0
- package/dist/assets/CenteredLoadingState-DHor-9vF.js.map +1 -0
- package/dist/assets/ChannelsPage-CbI0kqkd.js +2 -0
- package/dist/assets/ChannelsPage-CbI0kqkd.js.map +1 -0
- package/dist/assets/EmptyDataState-6mNx2Xhl.js +2 -0
- package/dist/assets/EmptyDataState-6mNx2Xhl.js.map +1 -0
- package/dist/assets/HelpPrompt-BPzDcC8F.js +2 -0
- package/dist/assets/HelpPrompt-BPzDcC8F.js.map +1 -0
- package/dist/assets/HomePage-t78sDDUj.js +2 -0
- package/dist/assets/HomePage-t78sDDUj.js.map +1 -0
- package/dist/assets/InspirationPage-BTqLpcHY.js +3 -0
- package/dist/assets/InspirationPage-BTqLpcHY.js.map +1 -0
- package/dist/assets/ModelsPage-YF0gpUxy.js +2 -0
- package/dist/assets/ModelsPage-YF0gpUxy.js.map +1 -0
- package/dist/assets/NameInitialIcon-DP-6_HQY.js +7 -0
- package/dist/assets/NameInitialIcon-DP-6_HQY.js.map +1 -0
- package/dist/assets/NoSearchResultsState-BiiYdZ_Z.js +2 -0
- package/dist/assets/NoSearchResultsState-BiiYdZ_Z.js.map +1 -0
- package/dist/assets/OverflowTooltip-CE5PjAb-.js +2 -0
- package/dist/assets/OverflowTooltip-CE5PjAb-.js.map +1 -0
- package/dist/assets/PasswordField-DmzjtnCg.js +2 -0
- package/dist/assets/PasswordField-DmzjtnCg.js.map +1 -0
- package/dist/assets/RefreshButton-BzYzeo5A.js +2 -0
- package/dist/assets/RefreshButton-BzYzeo5A.js.map +1 -0
- package/dist/assets/RightContentHeader-DoNDQ9Lo.js +3 -0
- package/dist/assets/RightContentHeader-DoNDQ9Lo.js.map +1 -0
- package/dist/assets/SchedulePage-CfW6lZVI.js +2 -0
- package/dist/assets/SchedulePage-CfW6lZVI.js.map +1 -0
- package/dist/assets/SearchInput-tux8xXH1.js +2 -0
- package/dist/assets/SearchInput-tux8xXH1.js.map +1 -0
- package/dist/assets/SkillAvatar-DwGvsY4f.js +2 -0
- package/dist/assets/SkillAvatar-DwGvsY4f.js.map +1 -0
- package/dist/assets/SkillsPage-ppqwKMvj.js +2 -0
- package/dist/assets/SkillsPage-ppqwKMvj.js.map +1 -0
- package/dist/assets/SkillsTab-c_As1DIr.css +1 -0
- package/dist/assets/SkillsTab-kY7MNdxy.js +2 -0
- package/dist/assets/SkillsTab-kY7MNdxy.js.map +1 -0
- package/dist/assets/Tab-FE0F2EQP.js +2 -0
- package/dist/assets/Tab-FE0F2EQP.js.map +1 -0
- package/dist/assets/ThreadPage-B0jElW5R.js +53 -0
- package/dist/assets/ThreadPage-B0jElW5R.js.map +1 -0
- package/dist/assets/UploadSkillModal-DHZL12vm.js +8 -0
- package/dist/assets/UploadSkillModal-DHZL12vm.js.map +1 -0
- package/dist/assets/XlsxDocumentPreview-BY-ht09K.js +5 -0
- package/dist/assets/XlsxDocumentPreview-BY-ht09K.js.map +1 -0
- package/dist/assets/_commonjs-dynamic-modules-TDtrdbi3.js +2 -0
- package/dist/assets/_commonjs-dynamic-modules-TDtrdbi3.js.map +1 -0
- package/dist/assets/chat-input-options-CpkOtPgQ.js +2 -0
- package/dist/assets/chat-input-options-CpkOtPgQ.js.map +1 -0
- package/dist/assets/docx-preview-zfB-orwa.js +28 -0
- package/dist/assets/docx-preview-zfB-orwa.js.map +1 -0
- package/dist/assets/exceljs.min-BY7KKJsM.js +58 -0
- package/dist/assets/exceljs.min-BY7KKJsM.js.map +1 -0
- package/dist/assets/helpers-CCilgpNy.js +2 -0
- package/dist/assets/helpers-CCilgpNy.js.map +1 -0
- package/dist/assets/hub-agent-editor.client-2DmCRGuY.js +2 -0
- package/dist/assets/hub-agent-editor.client-2DmCRGuY.js.map +1 -0
- package/dist/assets/hub-agent-editor.payload-D4sgJRSH.js +4 -0
- package/dist/assets/hub-agent-editor.payload-D4sgJRSH.js.map +1 -0
- package/dist/assets/hub-tag-editor-BBdd-aHK.js +2 -0
- package/dist/assets/hub-tag-editor-BBdd-aHK.js.map +1 -0
- package/dist/assets/index-Bed0I5IL.css +1 -0
- package/dist/assets/index-Bxf2_cvh.js +2 -0
- package/dist/assets/index-Bxf2_cvh.js.map +1 -0
- package/dist/assets/index-Cb4fQgom.js +103 -0
- package/dist/assets/index-Cb4fQgom.js.map +1 -0
- package/dist/assets/index-DQ2vVjmV.js +30 -0
- package/dist/assets/index-DQ2vVjmV.js.map +1 -0
- package/dist/assets/index-UBJEdbMO.js +2 -0
- package/dist/assets/index-UBJEdbMO.js.map +1 -0
- package/dist/assets/jszip.min-DPdj3o0t.js +13 -0
- package/dist/assets/jszip.min-DPdj3o0t.js.map +1 -0
- package/dist/assets/quick-actions-DzZE-zyP.js +2 -0
- package/dist/assets/quick-actions-DzZE-zyP.js.map +1 -0
- package/dist/assets/skill-options-cache-D1BJGTCU.js +2 -0
- package/dist/assets/skill-options-cache-D1BJGTCU.js.map +1 -0
- package/dist/assets/status-helpers-BILdm2MI.js +2 -0
- package/dist/assets/status-helpers-BILdm2MI.js.map +1 -0
- package/dist/assets/thread-title-Cerb2mHa.js +2 -0
- package/dist/assets/thread-title-Cerb2mHa.js.map +1 -0
- package/dist/assets/thread-utils-Ct3yp4R3.js +2 -0
- package/dist/assets/thread-utils-Ct3yp4R3.js.map +1 -0
- package/dist/assets/useAgentData-D-k9cXfg.js +2 -0
- package/dist/assets/useAgentData-D-k9cXfg.js.map +1 -0
- package/dist/assets/useEscapeKey-CEQ6-8GR.js +2 -0
- package/dist/assets/useEscapeKey-CEQ6-8GR.js.map +1 -0
- package/dist/assets/useExpertCatalog-BZdw1CYs.js +2 -0
- package/dist/assets/useExpertCatalog-BZdw1CYs.js.map +1 -0
- package/dist/assets/usePromptBlocks-5sz8Qh51.js +2 -0
- package/dist/assets/usePromptBlocks-5sz8Qh51.js.map +1 -0
- package/dist/assets/useSocket-YigidotN.css +1 -0
- package/dist/assets/useSocket-y3-zWhVL.js +11 -0
- package/dist/assets/useSocket-y3-zWhVL.js.map +1 -0
- package/dist/assets/utils--_pbLpCq.js +2 -0
- package/dist/assets/utils--_pbLpCq.js.map +1 -0
- package/dist/assets/vad-web-C_R267y1.js +2 -0
- package/dist/assets/vad-web-C_R267y1.js.map +1 -0
- package/dist/avatars/agent-avatar-1.png +0 -0
- package/dist/avatars/agent-avatar-2.png +0 -0
- package/dist/avatars/agent-avatar-3.png +0 -0
- package/dist/avatars/agent-avatar-4.png +0 -0
- package/dist/avatars/agent-avatar-5.png +0 -0
- package/dist/avatars/agent-avatar-6.png +0 -0
- package/dist/avatars/agent-avatar-7.png +0 -0
- package/dist/avatars/agent-avatar-8.png +0 -0
- package/dist/avatars/agent-avatar-9.png +0 -0
- package/dist/avatars/agentteams.png +0 -0
- package/dist/avatars/antig-opus.png +0 -0
- package/dist/avatars/antigravity.png +0 -0
- package/dist/avatars/assistant.svg +17 -0
- package/dist/avatars/codex-kawaii.png +0 -0
- package/dist/avatars/codex.png +0 -0
- package/dist/avatars/codex_box.png +0 -0
- package/dist/avatars/codex_iquid.png +0 -0
- package/dist/avatars/dare.png +0 -0
- package/dist/avatars/gemini-kawaii.png +0 -0
- package/dist/avatars/gemini.png +0 -0
- package/dist/avatars/gemini25.png +0 -0
- package/dist/avatars/gpt52.png +0 -0
- package/dist/avatars/jiuwenclaw.png +0 -0
- package/dist/avatars/office.svg +17 -0
- package/dist/avatars/opencode.png +0 -0
- package/dist/avatars/opus-45.png +0 -0
- package/dist/avatars/opus-kawaii.png +0 -0
- package/dist/avatars/opus.png +0 -0
- package/dist/avatars/sonnet.png +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/icons/arrow-left.svg +3 -0
- package/dist/icons/arrow-right.svg +3 -0
- package/dist/icons/attach.svg +9 -0
- package/dist/icons/chart/dislike.svg +3 -0
- package/dist/icons/chart/disliked.svg +3 -0
- package/dist/icons/chart/folder.svg +15 -0
- package/dist/icons/chart/home-loading.webp +0 -0
- package/dist/icons/chart/like.svg +3 -0
- package/dist/icons/chart/liked.svg +5 -0
- package/dist/icons/chart/loading.svg +26 -0
- package/dist/icons/chart/success.svg +7 -0
- package/dist/icons/check-line.svg +3 -0
- package/dist/icons/chevron-left.svg +3 -0
- package/dist/icons/chevron-right.svg +3 -0
- package/dist/icons/collapse.svg +14 -0
- package/dist/icons/common-delete.svg +4 -0
- package/dist/icons/common-folder.svg +4 -0
- package/dist/icons/copy.svg +4 -0
- package/dist/icons/cross-line.svg +4 -0
- package/dist/icons/data-analysis.svg +7 -0
- package/dist/icons/data-visualization.svg +10 -0
- package/dist/icons/deep-research.svg +4 -0
- package/dist/icons/document-processing.svg +5 -0
- package/dist/icons/edit.svg +4 -0
- package/dist/icons/expand.svg +6 -0
- package/dist/icons/expert-debate.svg +4 -0
- package/dist/icons/eye.svg +4 -0
- package/dist/icons/favicon.svg +7 -0
- package/dist/icons/file-docx.svg +60 -0
- package/dist/icons/file-folder.svg +4 -0
- package/dist/icons/file-gitignore.svg +35 -0
- package/dist/icons/file-html.svg +6 -0
- package/dist/icons/file-ini.svg +63 -0
- package/dist/icons/file-json.svg +4 -0
- package/dist/icons/file-md.svg +68 -0
- package/dist/icons/file-py.svg +4 -0
- package/dist/icons/file-sh.svg +7 -0
- package/dist/icons/file-txt.svg +37 -0
- package/dist/icons/file-zip.svg +21 -0
- package/dist/icons/file.svg +4 -0
- package/dist/icons/files-csv.svg +14 -0
- package/dist/icons/files-docx.svg +10 -0
- package/dist/icons/files-pdf.svg +14 -0
- package/dist/icons/files-ppt.svg +14 -0
- package/dist/icons/files-txt.svg +16 -0
- package/dist/icons/files-xlsx.svg +14 -0
- package/dist/icons/financial-services.svg +8 -0
- package/dist/icons/flie-html.svg +60 -0
- package/dist/icons/guided-mode.svg +9 -0
- package/dist/icons/icon-192x192.png +0 -0
- package/dist/icons/icon-512x512.png +0 -0
- package/dist/icons/icon-arrow-down.svg +4 -0
- package/dist/icons/icon-arrow-up.svg +4 -0
- package/dist/icons/icon-clear-all.svg +3 -0
- package/dist/icons/icon-close.svg +4 -0
- package/dist/icons/icon-code.svg +38 -0
- package/dist/icons/icon-drag-file.svg +26 -0
- package/dist/icons/icon-help.svg +4 -0
- package/dist/icons/icon-md.svg +53 -0
- package/dist/icons/icon-refresh.svg +4 -0
- package/dist/icons/icon-toggle.svg +6 -0
- package/dist/icons/icon-top.svg +7 -0
- package/dist/icons/icon-upload.svg +5 -0
- package/dist/icons/information.svg +6 -0
- package/dist/icons/inspiration/icon-excel.svg +14 -0
- package/dist/icons/inspiration/icon-inspiration.svg +5 -0
- package/dist/icons/inspiration/icon-markdown.svg +12 -0
- package/dist/icons/inspiration/icon-word.svg +10 -0
- package/dist/icons/link.svg +6 -0
- package/dist/icons/lock.svg +4 -0
- package/dist/icons/menu/agents.svg +39 -0
- package/dist/icons/menu/channels.svg +4 -0
- package/dist/icons/menu/icon-inspiration.svg +5 -0
- package/dist/icons/menu/models.svg +4 -0
- package/dist/icons/menu/new-chat.svg +59 -0
- package/dist/icons/menu/schedule.svg +4 -0
- package/dist/icons/menu/skills.svg +4 -0
- package/dist/icons/message-error.svg +6 -0
- package/dist/icons/message-prompt.svg +9 -0
- package/dist/icons/message-success.svg +6 -0
- package/dist/icons/message-warn.svg +8 -0
- package/dist/icons/more-trigger.svg +4 -0
- package/dist/icons/nss/1.svg +14 -0
- package/dist/icons/nss/2.svg +14 -0
- package/dist/icons/nss/3.svg +14 -0
- package/dist/icons/outline.svg +6 -0
- package/dist/icons/query_the_optical_power_border.svg +99 -0
- package/dist/icons/schedule.svg +4 -0
- package/dist/icons/settings-feedback/feedback-bug.svg +20 -0
- package/dist/icons/settings-feedback/feedback-file.svg +4 -0
- package/dist/icons/settings-feedback/feedback-idea.svg +14 -0
- package/dist/icons/settings-feedback/settings-gear.svg +4 -0
- package/dist/icons/settings-feedback/settings-link.svg +4 -0
- package/dist/icons/settings-feedback/settings-memory.svg +7 -0
- package/dist/icons/settings-feedback/settings-privacy.svg +37 -0
- package/dist/icons/settings-feedback/settings-search.svg +2 -0
- package/dist/icons/slides.svg +4 -0
- package/dist/icons/status/info-error.svg +9 -0
- package/dist/icons/style-template.svg +11 -0
- package/dist/icons/tool-error.svg +4 -0
- package/dist/icons/userprofile/help.svg +5 -0
- package/dist/icons/userprofile/keep-awake.svg +4 -0
- package/dist/icons/userprofile/question.svg +4 -0
- package/dist/icons/userprofile/security.svg +7 -0
- package/dist/icons/userprofile/style-template.svg +11 -0
- package/dist/icons/userprofile/theme.svg +14 -0
- package/dist/icons/userprofile/usage.svg +4 -0
- package/dist/icons/userprofile/version.svg +85 -0
- package/dist/icons/video-generation.svg +4 -0
- package/dist/images/OfficeClaw.svg +21 -0
- package/dist/images/add.svg +4 -0
- package/dist/images/agent-management-icons/agent-check.svg +23 -0
- package/dist/images/agent-management-icons/agent-close.svg +4 -0
- package/dist/images/agent-management-icons/agent-collab.svg +4 -0
- package/dist/images/agent-management-icons/agent-delete.svg +18 -0
- package/dist/images/agent-management-icons/agent-edit.svg +18 -0
- package/dist/images/agent-management-icons/agent-more.svg +4 -0
- package/dist/images/agent-management-icons/agent-persona.svg +4 -0
- package/dist/images/agent-management-icons/agent-random-avatar.svg +39 -0
- package/dist/images/agent-management-icons/agent-refresh.svg +4 -0
- package/dist/images/agent-management-icons/agent-skills.svg +4 -0
- package/dist/images/agent-management-icons/agent-template.svg +12 -0
- package/dist/images/agent-management-icons/anchor-current.svg +5 -0
- package/dist/images/agent-management-icons/anchor-other.svg +4 -0
- package/dist/images/chat-empty-agent.svg +12 -0
- package/dist/images/chat-empty-im.svg +14 -0
- package/dist/images/connectors/dingtalk.png +0 -0
- package/dist/images/connectors/dingtalk.svg +18 -0
- package/dist/images/connectors/feishu.png +0 -0
- package/dist/images/connectors/feishu.svg +12 -0
- package/dist/images/connectors/imessage.png +0 -0
- package/dist/images/connectors/wecom-agent.png +0 -0
- package/dist/images/connectors/wecom-bot.png +0 -0
- package/dist/images/connectors/weixin.png +0 -0
- package/dist/images/connectors/weixin.svg +19 -0
- package/dist/images/connectors/xiaoyi.png +0 -0
- package/dist/images/connectors/xiaoyi.svg +12 -0
- package/dist/images/create-agent-random-avatar.svg +39 -0
- package/dist/images/deepseek.svg +1 -0
- package/dist/images/default-ppt-template.png +0 -0
- package/dist/images/file-browser-tree/code.svg +60 -0
- package/dist/images/file-browser-tree/gitignore.svg +35 -0
- package/dist/images/file-browser-tree/image.svg +12 -0
- package/dist/images/file-browser-tree/markdown.svg +68 -0
- package/dist/images/file-browser-tree/pdf.svg +4 -0
- package/dist/images/file-browser-tree/ppt.svg +4 -0
- package/dist/images/file-browser-tree/public-file.svg +37 -0
- package/dist/images/file-browser-tree/word.svg +60 -0
- package/dist/images/file-browser-tree/xlsx.svg +4 -0
- package/dist/images/html-preview-toolbar/copy.svg +4 -0
- package/dist/images/html-preview-toolbar/open-external.svg +4 -0
- package/dist/images/html-preview-toolbar/refresh.svg +4 -0
- package/dist/images/information.svg +4 -0
- package/dist/images/inspiration/blue-bg.png +0 -0
- package/dist/images/inspiration/doc-example.png +0 -0
- package/dist/images/inspiration/excel-example.png +0 -0
- package/dist/images/inspiration/green-bg.png +0 -0
- package/dist/images/inspiration/markdown-example.png +0 -0
- package/dist/images/inspiration/orange-bg.png +0 -0
- package/dist/images/inspiration/purple-bg.png +0 -0
- package/dist/images/inspiration/task-bg.png +0 -0
- package/dist/images/inspiration-bg.png +0 -0
- package/dist/images/inspiration-products/default.svg +11 -0
- package/dist/images/invitation-background-4x.png +0 -0
- package/dist/images/kimi.svg +1 -0
- package/dist/images/link-blue.svg +4 -0
- package/dist/images/link.svg +4 -0
- package/dist/images/lobster.svg +118 -0
- package/dist/images/login1.svg +93 -0
- package/dist/images/login2.svg +80 -0
- package/dist/images/login3.svg +44 -0
- package/dist/images/login4.svg +18 -0
- package/dist/images/mode-default-icon.svg +22 -0
- package/dist/images/no-data.svg +26 -0
- package/dist/images/no-search-results.svg +25 -0
- package/dist/images/ppt-preview/placeholder-main.webp +0 -0
- package/dist/images/ppt-preview/placeholder-thumb.webp +0 -0
- package/dist/images/ppt-template/dark-tech.png +0 -0
- package/dist/images/ppt-template/huawei.png +0 -0
- package/dist/images/ppt-template/light-tech.png +0 -0
- package/dist/images/ppt-template/paper-humanities.png +0 -0
- package/dist/images/ppt-template/template-default.png +0 -0
- package/dist/images/ppt-template/template-error.png +0 -0
- package/dist/images/ppt-template/template-generate-bg.svg +9639 -0
- package/dist/images/qwen.svg +1 -0
- package/dist/images/task-list/empty-state.svg +4 -0
- package/dist/images/task-list.svg +1 -0
- package/dist/images/vendor.svg +4 -0
- package/dist/images/version-bg.svg +85 -0
- package/dist/images/version.svg +9 -0
- package/dist/images/zhipu.svg +1 -0
- package/dist/index.html +74 -0
- package/dist/loading-point-style.webp +0 -0
- package/dist/loading-small.webp +0 -0
- package/dist/manifest.json +25 -0
- package/package.json +126 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentsPage-2u2kFBCH.js","sources":["../../src/components/agent-management/components/Card.tsx","../../src/components/agent-management/constants.ts","../../src/components/agent-management/components/ListGrid.tsx","../../src/components/agent-management/components/Toolbar.tsx","../../src/components/agent-management/components/DetailContent.tsx","../../src/components/agent-management/components/skill-basic-info-cache.ts","../../src/components/agent-management/components/DetailSkillsSection.tsx","../../src/components/agent-management/components/MarkdownEditor.tsx","../../src/components/agent-management/components/MarkdownEditorWrapper.tsx","../../src/components/agent-management/components/SoulConfig.tsx","../../src/components/agent-management/utils.ts","../../src/utils/agent-save-error.ts","../../src/components/agent-management/components/ModelSelectDropdown.tsx","../../src/components/agent-management/components/BasicInfoSection.tsx","../../src/components/agent-management/components/FormFooter.tsx","../../src/components/agent-management/components/FormHeader.tsx","../../src/components/agent-management/hooks/useInstallStatus.ts","../../src/components/agent-management/hooks/useSkillSearch.ts","../../src/components/agent-management/hooks/useSkillInstall.ts","../../src/components/agent-management/components/SkillSelectorDrawer.tsx","../../src/components/agent-management/components/FormSkillsSection.tsx","../../src/components/PromptSelectionModal.tsx","../../src/components/agent-management/components/FormSoulSection.tsx","../../src/components/agent-management/components/FormStepNav.tsx","../../src/components/agent-management/hooks/useFormStepScroll.ts","../../src/components/agent-management/hooks/useModelMenu.ts","../../src/components/agent-management/hooks/useModelSelection.ts","../../src/components/agent-management/hooks/useAvatarUpload.ts","../../src/components/agent-management/components/FormContent.tsx","../../src/components/agent-management/AgentManagementView.tsx","../../src/components/agent-management/hooks/usePanelState.ts","../../src/components/agent-management/AgentManagement.tsx","../../src/components/experts-panel/types/expert.ts","../../src/components/experts-panel/components/ExpertCard.tsx","../../src/components/experts-panel/components/ExpertCardGrid.tsx","../../src/components/experts-panel/components/SelectSessionModal.tsx","../../src/components/experts-panel/hooks/useExperts.ts","../../src/components/experts-panel/ExpertsPanel.tsx","../../src/components/AgentsPanel.tsx","../../src/pages/AgentsPage.tsx"],"sourcesContent":["import type { AgentData } from '@/hooks/useAgentData';\n\nexport interface CardProps {\n agent: AgentData;\n onClick: (agentId: string) => void;\n onEdit?: (agentId: string) => void;\n onDelete?: (agentId: string) => void;\n}\n\nfunction getNameInitial(name?: string): string {\n if (!name) return '智';\n return name.slice(0, 1).toUpperCase();\n}\n\nfunction getNameInitialTheme(name: string): { background: string; borderColor: string; textColor: string } {\n const colors = [\n { bg: '#FFF4E6', border: '#FFE0B2', text: '#E65100' },\n { bg: '#E3F2FD', border: '#BBDEFB', text: '#1565C0' },\n { bg: '#F3E5F5', border: '#E1BEE7', text: '#7B1FA2' },\n { bg: '#E8F5E9', border: '#C8E6C9', text: '#2E7D32' },\n { bg: '#FFF3E0', border: '#FFE0B2', text: '#E65100' },\n { bg: '#E0F7FA', border: '#B2EBF2', text: '#00838F' },\n { bg: '#FCE4EC', border: '#F8BBD0', text: '#C2185B' },\n { bg: '#F1F8E9', border: '#DCEDC8', text: '#558B2F' },\n ];\n const index = name.charCodeAt(0) % colors.length;\n return {\n background: colors[index].bg,\n borderColor: colors[index].border,\n textColor: colors[index].text,\n };\n}\n\nfunction Avatar({ agent }: { agent: AgentData }) {\n const avatar = agent.avatar?.trim();\n if (avatar && (avatar.startsWith('/uploads/') || avatar.startsWith('/avatars/') || /^https?:\\/\\//.test(avatar))) {\n return (\n // biome-ignore lint/performance/noImgElement: runtime upload URL\n <img src={avatar} alt={agent.displayName} className=\"h-12 w-12 shrink-0 rounded-full object-cover\" />\n );\n }\n\n const name = agent.displayName ?? agent.name ?? '智';\n const theme = getNameInitialTheme(name);\n\n return (\n <div\n aria-hidden=\"true\"\n className=\"inline-flex h-12 w-12 shrink-0 items-center justify-center rounded-full border shadow-sm\"\n style={{ background: theme.background, borderColor: theme.borderColor }}\n >\n <span className=\"select-none text-xl font-bold leading-none tracking-[0.02em]\" style={{ color: theme.textColor }}>\n {getNameInitial(name)}\n </span>\n </div>\n );\n}\n\nexport function Card({ agent, onClick, onEdit, onDelete }: CardProps) {\n const modelText = agent.defaultModel || '未配置模型';\n const sourceText =\n agent.source === 'seed' ? '预置' : agent.creationSource === 'experts-plaza' ? '智能体广场' : '自定义';\n\n return (\n <article\n className=\"ui-card ui-card-hover group relative flex h-[196px] cursor-pointer flex-col rounded-[16px] border border-[#e6e6e6] bg-white p-6\"\n onClick={() => onClick(agent.id)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onClick(agent.id);\n }\n }}\n role=\"button\"\n tabIndex={0}\n aria-label={`查看智能体 ${agent.displayName}`}\n >\n <div className=\"mb-4 flex items-start gap-3\">\n <Avatar agent={agent} />\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate text-[14px] font-semibold text-[var(--text-primary)]\">{agent.displayName}</h3>\n <p className=\"mt-1 truncate text-[12px] text-[var(--text-muted)]\">{modelText}</p>\n </div>\n </div>\n\n {agent.roleDescription ? (\n <p className=\"line-clamp-2 mb-4 flex-1 text-[12px] leading-relaxed text-[var(--text-secondary)]\">{agent.roleDescription}</p>\n ) : (\n <p className=\"line-clamp-2 mb-4 flex-1 text-[12px] leading-relaxed text-[var(--text-muted)]\">暂无描述</p>\n )}\n\n <div\n className={`mt-auto flex items-center justify-between text-[12px] text-[var(--text-muted)] transition-opacity ${\n onEdit || onDelete ? 'group-hover:opacity-0 group-hover:pointer-events-none group-focus-within:opacity-0 group-focus-within:pointer-events-none' : ''\n }`}\n >\n <span>来源:{sourceText}</span>\n </div>\n\n <div\n className={`absolute bottom-6 left-6 right-6 flex items-center gap-4 transition-opacity ${\n onEdit || onDelete ? 'opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto group-focus-within:opacity-100 group-focus-within:pointer-events-auto' : ''\n }`}\n >\n {onEdit && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit(agent.id);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.stopPropagation();\n onEdit(agent.id);\n }\n }}\n className=\"bg-transparent p-0 text-[14px] font-normal text-[var(--text-accent)] hover:underline\"\n >\n 编辑\n </button>\n )}\n {onDelete && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(agent.id);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.stopPropagation();\n onDelete(agent.id);\n }\n }}\n className=\"bg-transparent p-0 text-[14px] font-normal text-[var(--text-accent)] hover:underline\"\n >\n 删除\n </button>\n )}\n </div>\n </article>\n );\n}","import type { InspirationTemplate } from './types';\n\nexport const AGENT_LIST_GRID_CLASS = 'grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4';\n\nexport const AGENT_CARD_BASE_CLASS =\n 'group relative flex flex-col rounded-lg border p-4 transition-colors cursor-pointer';\n\nexport const AGENT_CARD_DEFAULT_CLASS =\n 'border-[var(--connector-tab-border-default)] bg-[var(--connector-tab-bg-default)] hover:border-[var(--connector-tab-border-hover)] hover:bg-[var(--connector-tab-bg-hover)]';\n\nexport const AGENT_CARD_SELECTED_CLASS =\n 'border-[var(--connector-tab-border-selected)] bg-[var(--connector-tab-bg-selected)]';\n\nexport const FORM_STEPS = [\n { id: 'basic', label: '基础信息' },\n { id: 'soul', label: '灵魂配置' },\n { id: 'skills', label: '技能配置' },\n] as const;\n\nexport type FormStepId = (typeof FORM_STEPS)[number]['id'];\n\nexport const TEMPLATE_PAGE_SIZE = 4;\n\nexport const MODEL_MENU_MAX_HEIGHT = 335;\nexport const MODEL_MENU_OFFSET = 8;\nexport const HUAWEI_GROUP_LABEL = '华为云 MaaS';\nexport const HUAWEI_PROVIDER_LABEL = 'Huawei MaaS';\nexport const THIRD_PARTY_GROUP_LABEL = '第三方模型';\nexport const RELAYCLAW_CLIENT = 'relayclaw';\n\nexport const AGENT_NAME_VALIDATION_MESSAGE =\n '支持中文、数字、下划线、中划线和空格,长度 2-64 字符,但不允许以空格开头或结尾';\n\nexport const PRESET_AVATARS = [\n '/avatars/agent-avatar-1.png',\n '/avatars/agent-avatar-2.png',\n '/avatars/agent-avatar-3.png',\n '/avatars/agent-avatar-4.png',\n '/avatars/agent-avatar-5.png',\n '/avatars/agent-avatar-6.png',\n '/avatars/agent-avatar-7.png',\n '/avatars/agent-avatar-8.png',\n '/avatars/agent-avatar-9.png',\n];\n\nexport const DEFAULT_PRESET_AVATAR = PRESET_AVATARS[0];\n\nexport const INSPIRATION_TEMPLATES: InspirationTemplate[] = [\n {\n id: 'customer-service',\n title: '专业客服助手',\n description: '遵循服务规范,礼貌应答、流程引导、问题定位与转接支持,严格遵守业务边界。',\n content: `### 人格定义 (Persona)\n- 身份:资深客服顾问,擅长复杂问题拆解与安抚沟通。\n- 性格:耐心克制、语气专业、表达清晰。\n- 边界:优先给流程和升级路径,不承诺超出权限范围的结果。\n\n### 行为准则 (Behavior)\n- 精准识别用户诉求与情绪波动,先安抚再给处理路径。\n- 优先提供标准流程与升级建议,避免模糊表述。\n- 回复中同步标注下一步动作和责任归属,方便继续跟进。`,\n },\n {\n id: 'content-creation',\n title: '内容创作助手',\n description: '支持文案策写、标题优化、脚本创作与风格适配,结构清晰,表达自然。',\n content: `### 人格定义 (Persona)\n- 身份:资深内容创作者,擅长短视频脚本、公众号与朋友圈文案。\n- 性格:创意灵活、洞察强,适配多平台风格。\n- 边界:只提供创作思路和文案优化,不涉及侵权内容。\n\n### 行为准则 (Behavior)\n- 先明确平台、受众、核心卖点与风格,再组织内容结构。\n- 快速提供多版初稿,并标注亮点和适用场景。\n- 根据反馈迭代修改,同时说明调整重点和原因。`,\n },\n {\n id: 'knowledge-answering',\n title: '知识解答专家',\n description: '以严谨准确为原则,科普概念、拆解原理、解释规则,输出可信且有条理。',\n content: `### 人格定义 (Persona)\n- 身份:知识顾问,擅长多源信息整合与严谨解释。\n- 性格:理性克制、客观中立、注重依据。\n- 边界:不制造未经验证的结论,需要时先补充上下文。\n\n### 行为准则 (Behavior)\n- 先确认问题边界和上下文,再给出结构化解释。\n- 需要时补充适用范围、风险提醒和可执行建议。\n- 输出以结论、依据、行动项三段式为主,便于快速吸收。`,\n },\n {\n id: 'work-efficiency',\n title: '职场效率助手',\n description: '提供沟通话术、汇报提纲、流程梳理与决策辅助,帮助提升交付效率。',\n content: `### 人格定义 (Persona)\n- 身份:项目协作教练,擅长流程梳理与任务推进。\n- 性格:简洁务实、节奏明确、结果导向。\n- 边界:优先提升沟通和推进效率,不替代最终业务判断。\n\n### 行为准则 (Behavior)\n- 优先沉淀行动项、责任人和时间节点。\n- 必要时给出沟通模板、纪要模板和复盘建议。\n- 遇到阻塞时先拆原因,再提供可落地的替代方案。`,\n },\n {\n id: 'project-management',\n title: '项目管理助手',\n description: '帮助拆解目标、制定里程碑、推动协作与风险跟踪,保持推进节奏清晰。',\n content: `### 人格定义 (Persona)\n- 身份:项目经理与交付协调者,擅长推进计划落地。\n- 性格:稳健清晰、节奏明确、关注依赖关系。\n- 边界:聚焦项目推进与协作管理,不替代业务 owner 决策。\n\n### 行为准则 (Behavior)\n- 先明确目标与边界,再拆解任务、识别风险并推动闭环。\n- 围绕依赖关系和优先级安排里程碑与检查点。\n- 产出默认带负责人、时间节点和跟踪建议。`,\n },\n {\n id: 'data-analysis',\n title: '数据分析助手',\n description: '聚焦指标拆解、数据解读、洞察归纳与结论表达,适合业务分析场景。',\n content: `### 人格定义 (Persona)\n- 身份:数据分析师,擅长从指标与样本中提炼业务洞察。\n- 性格:严谨客观、表达简洁、重视证据。\n- 边界:不在样本不足时输出确定性结论,会明确说明口径和限制。\n\n### 行为准则 (Behavior)\n- 先确认指标口径与样本范围,再给出分析过程。\n- 输出结论时同步说明依据、异常点和建议动作。\n- 默认补充图表建议、后续验证方向和数据缺口。`,\n },\n];\n\nexport function buildTemplateMarkdown(template: InspirationTemplate): string {\n return `## ${template.title}\\n\\n${template.content}`;\n}\n","import type { AgentData } from '@/hooks/useAgentData';\nimport { EmptyDataState } from '@/components/shared/EmptyDataState';\nimport { NoSearchResultsState } from '@/components/shared/NoSearchResultsState';\nimport { Card } from './Card';\nimport { AGENT_LIST_GRID_CLASS } from '../constants';\nimport type { AgentSourceFilter } from '../utils';\n\nexport interface ListGridProps {\n agents: AgentData[];\n onSelectAgent: (agentId: string) => void;\n onEditAgent?: (agentId: string) => void;\n onDeleteAgent?: (agentId: string) => void;\n searchQuery?: string;\n sourceFilter?: AgentSourceFilter;\n onClearSearch?: () => void;\n onClearFilter?: () => void;\n}\n\nexport function ListGrid({\n agents,\n onSelectAgent,\n onEditAgent,\n onDeleteAgent,\n searchQuery = '',\n sourceFilter = 'all',\n onClearSearch,\n onClearFilter,\n}: ListGridProps) {\n if (agents.length === 0) {\n if (searchQuery.trim() || sourceFilter !== 'all') {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <NoSearchResultsState\n onClear={() => {\n onClearSearch?.();\n onClearFilter?.();\n }}\n />\n </div>\n );\n }\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <EmptyDataState title=\"暂无智能体\" />\n </div>\n );\n }\n\n return (\n <div className={AGENT_LIST_GRID_CLASS}>\n {agents.map((agent) => (\n <Card\n key={agent.id}\n agent={agent}\n onClick={onSelectAgent}\n onEdit={onEditAgent}\n onDelete={onDeleteAgent}\n />\n ))}\n </div>\n );\n}","import { useState } from 'react';\nimport { Button } from '@/components/shared/Button';\nimport { SearchInput } from '@/components/shared/SearchInput';\nimport { RefreshButton } from '@/components/shared/RefreshButton';\nimport type { AgentSourceFilter } from '../utils';\n\nexport interface ToolbarProps {\n searchQuery: string;\n sourceFilter: AgentSourceFilter;\n onSearchChange: (query: string) => void;\n onClearSearch: () => void;\n onSourceFilterChange: (filter: AgentSourceFilter) => void;\n onRefresh: () => void;\n loading?: boolean;\n}\n\nconst SOURCE_FILTER_OPTIONS: Array<{ value: AgentSourceFilter; label: string }> = [\n { value: 'all', label: '全部' },\n { value: 'seed', label: '预置智能体' },\n { value: 'runtime', label: '自定义' },\n { value: 'experts-plaza', label: '智能体广场' },\n];\n\nexport function Toolbar({\n searchQuery,\n sourceFilter,\n onSearchChange,\n onClearSearch,\n onSourceFilterChange,\n onRefresh,\n loading,\n}: ToolbarProps) {\n const [sourceMenuOpen, setSourceMenuOpen] = useState(false);\n\n const activeSourceLabel = SOURCE_FILTER_OPTIONS.find((opt) => opt.value === sourceFilter)?.label ?? '全部';\n\n return (\n <div className=\"flex w-full items-center gap-3\">\n <div className=\"relative w-[120px] shrink-0\">\n <select\n aria-label=\"筛选来源\"\n value={sourceFilter}\n onChange={(e) => onSourceFilterChange(e.target.value as AgentSourceFilter)}\n className=\"sr-only\"\n tabIndex={-1}\n >\n {SOURCE_FILTER_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n onClick={() => setSourceMenuOpen((prev) => !prev)}\n className={`ui-field flex h-[28px] w-[120px] items-center justify-between rounded-[6px] px-[12px] py-[5px] text-xs transition-colors ${sourceMenuOpen ? 'border-[#191919]' : ''}`}\n aria-haspopup=\"listbox\"\n aria-expanded={sourceMenuOpen}\n >\n <span className=\"truncate text-[var(--text-primary)]\">{activeSourceLabel}</span>\n <svg\n className={`h-3.5 w-3.5 text-[var(--text-muted)] transition-transform duration-200 ${sourceMenuOpen ? 'rotate-180' : ''}`}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path d=\"M4 6L8 10L12 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n {sourceMenuOpen ? (\n <div\n role=\"listbox\"\n className=\"absolute left-0 top-[calc(100%+4px)] z-30 w-[120px] rounded-[6px] bg-[var(--surface-panel)] py-[8px] shadow-[0_2px_12px_0_var(--tooltip-shadow-color)]\"\n >\n {SOURCE_FILTER_OPTIONS.map((opt) => {\n const isSelected = opt.value === sourceFilter;\n return (\n <button\n key={opt.value}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => {\n onSourceFilterChange(opt.value);\n setSourceMenuOpen(false);\n }}\n className={`flex h-[32px] w-full items-center px-[16px] py-[7px] text-left text-xs transition-colors hover:bg-[var(--tag-bg)] ${isSelected ? 'text-[var(--text-accent)]' : 'text-[var(--text-primary)]'}`}\n >\n {opt.label}\n </button>\n );\n })}\n </div>\n ) : null}\n </div>\n <SearchInput\n value={searchQuery}\n onChange={onSearchChange}\n onClear={onClearSearch}\n placeholder=\"搜索智能体\"\n aria-label=\"搜索智能体\"\n clearAriaLabel=\"清除搜索\"\n wrapperClassName=\"flex-1\"\n />\n <RefreshButton\n onClick={onRefresh}\n disabled={loading}\n aria-label=\"刷新列表\"\n />\n </div>\n );\n}\n","import type { AgentData } from '@/hooks/useAgentData';\nimport { OverflowTooltip } from '@/components/shared/OverflowTooltip';\nimport { HelpPrompt } from '@/components/shared/HelpPrompt';\n\nexport interface DetailContentProps {\n agent: AgentData;\n}\n\nexport function DetailContent({ agent }: DetailContentProps) {\n const modelText = agent.defaultModel || '未配置模型';\n const imageModelText = agent.imageModel || '未配置';\n\n return (\n <div className=\"flex flex-col gap-4 pb-8\">\n <h2 className=\"text-[16px] font-semibold text-[var(--text-primary)]\">基础信息</h2>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <div className=\"min-w-0 flex flex-col gap-2\">\n <h2 className=\"text-[12px] font-medium text-[var(--text-muted)]\">描述</h2>\n <OverflowTooltip\n content={agent.roleDescription || '暂无描述'}\n className=\"block w-full min-w-0\"\n placement=\"top\"\n >\n <span className=\"block min-w-0 truncate text-[14px] text-[var(--text-primary)]\">\n {agent.roleDescription || '暂无描述'}\n </span>\n </OverflowTooltip>\n </div>\n\n <div className=\"min-w-0 flex flex-col gap-2\">\n <div className=\"flex items-center gap-1.5\">\n <h2 className=\"text-[12px] font-medium text-[var(--text-muted)]\">主模型</h2>\n <HelpPrompt tooltip=\"负责思考、推理、生成文本输出\" ariaLabel=\"主模型说明\" />\n </div>\n <p className=\"break-words text-[14px] text-[var(--text-primary)]\">{modelText}</p>\n </div>\n\n <div className=\"min-w-0 flex flex-col gap-2\">\n <div className=\"flex items-center gap-1.5\">\n <h2 className=\"text-[12px] font-medium text-[var(--text-muted)]\">图像理解模型(可选)</h2>\n <HelpPrompt tooltip=\"用于对图片内容的识别场景,对图片附件进行处理\" ariaLabel=\"图像理解模型说明\" />\n </div>\n <p className=\"break-words text-[14px] text-[var(--text-primary)]\">{imageModelText}</p>\n </div>\n </div>\n </div>\n );\n}","/*\n * *\n * * Copyright (C) Huawei Technologies Co., Ltd. 2026. All rights reserved.\n *\n */\n\n/**\n * Skill Basic Info Cache\n *\n * 用于缓存已安装技能的基本信息(名称、描述),避免在详情页重复请求。\n *\n * 使用场景:\n * - SkillSelectorDrawer 加载已安装技能列表时,自动填充缓存\n * - DetailSkillsSection 显示技能卡片时,直接从缓存读取描述\n * - 技能安装/卸载时无需额外操作(SkillSelectorDrawer 重新加载时会更新缓存)\n *\n * 注意:此缓存是内存缓存,页面刷新后会重新从 SkillSelectorDrawer 加载\n */\n\n/**\n * 技能基本信息\n */\nexport interface SkillBasicInfo {\n /** 技能名称 */\n name: string;\n /** 技能描述(可选) */\n description?: string;\n}\n\n// 缓存 Map:技能名称 -> 技能基本信息\nlet cachedSkillBasicInfos: Map<string, SkillBasicInfo> = new Map();\n\n/**\n * 获取单个技能的基本信息\n * @param skillName 技能名称\n * @returns 技能基本信息,如果缓存不存在则返回 undefined\n */\nexport function getSkillBasicInfo(skillName: string): SkillBasicInfo | undefined {\n return cachedSkillBasicInfos.get(skillName);\n}\n\n/**\n * 存储单个技能的基本信息到缓存\n * @param skillName 技能名称\n * @param info 技能基本信息\n */\nexport function setSkillBasicInfo(skillName: string, info: SkillBasicInfo): void {\n cachedSkillBasicInfos.set(skillName, info);\n}\n\n/**\n * 批量存储技能基本信息到缓存\n * @param infos 技能基本信息数组\n */\nexport function setMultipleSkillBasicInfos(infos: SkillBasicInfo[]): void {\n infos.forEach((info) => {\n cachedSkillBasicInfos.set(info.name, info);\n });\n}\n\n/**\n * 从缓存中移除指定技能的信息\n * @param skillName 技能名称\n */\nexport function removeSkillBasicInfo(skillName: string): void {\n cachedSkillBasicInfos.delete(skillName);\n}\n\n/**\n * 获取缓存中所有技能基本信息的拷贝\n * @returns 包含所有技能信息的 Map 拷贝\n */\nexport function getAllSkillBasicInfos(): Map<string, SkillBasicInfo> {\n return new Map(cachedSkillBasicInfos);\n}\n\n/**\n * 清空技能基本信息缓存\n */\nexport function clearSkillBasicInfoCache(): void {\n cachedSkillBasicInfos.clear();\n}","import { useEffect, useState } from 'react';\nimport type { AgentData } from '@/hooks/useAgentData';\nimport { NameInitialIcon } from '@/components/NameInitialIcon';\nimport { getSkillBasicInfo, setSkillBasicInfo } from './skill-basic-info-cache';\nimport { apiFetch } from '@/utils/api-client';\nimport styles from './DetailSkillsSection.module.css';\n\nexport interface DetailSkillsSectionProps {\n agent: AgentData;\n}\n\ninterface SkillDetailResponse {\n name: string;\n description?: string;\n category?: string;\n triggers?: string[];\n}\n\nexport function DetailSkillsSection({ agent }: DetailSkillsSectionProps) {\n const skills = agent.skills;\n const [loadingSkills, setLoadingSkills] = useState<Set<string>>(new Set());\n\n useEffect(() => {\n if (!skills || skills.length === 0) return;\n\n // Check which skills are missing from cache and need to be fetched\n const missingSkills = skills.filter((name) => !getSkillBasicInfo(name));\n if (missingSkills.length === 0) return;\n\n setLoadingSkills(new Set(missingSkills));\n\n // Fetch details for missing skills in parallel\n Promise.all(\n missingSkills.map(async (skillName) => {\n try {\n const res = await apiFetch(`/api/skills/detail?name=${encodeURIComponent(skillName)}`);\n if (res.ok) {\n const data = (await res.json()) as SkillDetailResponse;\n setSkillBasicInfo(skillName, {\n name: data.name,\n description: data.description,\n });\n }\n } finally {\n setLoadingSkills((prev) => {\n const next = new Set(prev);\n next.delete(skillName);\n return next;\n });\n }\n }),\n );\n }, [skills]);\n\n return (\n <div className=\"flex flex-col gap-4\">\n <h2 className=\"text-[16px] font-semibold text-[var(--text-primary)]\">技能配置</h2>\n\n {skills && skills.length > 0 ? (\n <div className={styles.skillGrid}>\n {skills.map((skillName) => {\n const skillInfo = getSkillBasicInfo(skillName);\n const isLoading = loadingSkills.has(skillName);\n return (\n <div key={skillName} className={styles.skillCard}>\n <NameInitialIcon name={skillName} className={styles.cardIcon} />\n <div className={styles.cardContent}>\n <span className={styles.cardName}>{skillName}</span>\n {isLoading ? (\n <span className={styles.cardDescription}>加载中...</span>\n ) : (\n skillInfo?.description && (\n <span className={styles.cardDescription}>{skillInfo.description}</span>\n )\n )}\n </div>\n </div>\n );\n })}\n </div>\n ) : (\n <p className={styles.emptyState}>未配置</p>\n )}\n </div>\n );\n}","import type { RefObject } from 'react';\nimport type { InspirationTemplate } from '../types';\nimport { buildTemplateMarkdown } from '../constants';\nimport { Button } from '@/components/shared/Button';\nimport { MarkdownContent } from '@/components/MarkdownContent';\nimport { OverflowTooltip } from '@/components/shared/OverflowTooltip';\n\nfunction ChevronLeftIcon(props: { className?: string }) {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\" className={props.className}>\n <path d=\"M15 6L9 12L15 18\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n );\n}\n\nfunction ChevronRightIcon(props: { className?: string }) {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\" className={props.className}>\n <path d=\"M9 6L15 12L9 18\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n );\n}\n\nexport interface MarkdownEditorProps {\n activeTab: 'persona' | 'collab';\n activeWorkingDraft: string;\n editorSurfaceRef: RefObject<HTMLDivElement | null>;\n editorTextareaRef: RefObject<HTMLTextAreaElement | null>;\n isPersonaEmpty: boolean;\n onApplyTemplate: (templateId: string) => void;\n onAfterApplyTemplate?: () => void;\n onDraftChange: (value: string) => void;\n onNextTemplatePage: () => void;\n onPrevTemplatePage: () => void;\n templatePage: number;\n templatePageCount: number;\n visibleTemplates: InspirationTemplate[];\n appliedTemplateKey?: number;\n}\n\nexport function MarkdownEditor({\n activeTab,\n activeWorkingDraft,\n editorSurfaceRef,\n editorTextareaRef,\n isPersonaEmpty,\n onApplyTemplate,\n onAfterApplyTemplate,\n onDraftChange,\n onNextTemplatePage,\n onPrevTemplatePage,\n templatePage,\n templatePageCount,\n visibleTemplates,\n appliedTemplateKey,\n}: MarkdownEditorProps) {\n const showTemplates = activeTab === 'persona';\n\n return (\n <div\n data-testid={isPersonaEmpty ? 'agent-tab-empty-editor' : 'agent-tab-editor'}\n className=\"relative flex min-h-0 flex-1 flex-col p-4 h-full\"\n >\n <div ref={editorSurfaceRef as RefObject<HTMLDivElement>} className=\"min-h-0 flex-1\">\n <textarea\n ref={editorTextareaRef as RefObject<HTMLTextAreaElement>}\n value={activeWorkingDraft}\n onChange={(event) => onDraftChange(event.target.value)}\n placeholder=\"请输入你的智能体人格、语气、规则描述,或选择下方模板自动生成\"\n className=\"ui-textarea ui-textarea-plain block h-full min-h-0 w-full resize-none overflow-y-auto rounded-none text-[12px] leading-7\"\n data-testid=\"agent-tab-textarea\"\n />\n </div>\n\n {showTemplates ? (\n <div className={`${isPersonaEmpty ? 'mt-4' : 'mt-4'} flex shrink-0 flex-col ${isPersonaEmpty ? '' : 'hidden'}`}>\n <div className=\"mx-auto w-full\">\n <div className=\"mb-2 flex items-center justify-between gap-3 text-[12px] text-[var(--text-muted)]\">\n <span>灵魂模板</span>\n {templatePageCount > 1 ? (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={onPrevTemplatePage}\n disabled={templatePage === 0}\n className=\"inline-flex h-6 w-6 items-center justify-center rounded-full text-[var(--text-muted)] transition enabled:hover:bg-[var(--surface-card-muted)] disabled:cursor-not-allowed disabled:opacity-40\"\n aria-label=\"上一页模板\"\n >\n <ChevronLeftIcon className=\"h-3.5 w-3.5\" />\n </button>\n <button\n type=\"button\"\n onClick={onNextTemplatePage}\n disabled={templatePage >= templatePageCount - 1}\n className=\"inline-flex h-6 w-6 items-center justify-center rounded-full text-[var(--text-muted)] transition enabled:hover:bg-[var(--surface-card-muted)] disabled:cursor-not-allowed disabled:opacity-40\"\n aria-label=\"下一页模板\"\n >\n <ChevronRightIcon className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n ) : null}\n </div>\n\n <div className=\"grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-4\">\n {visibleTemplates.map((template) => (\n <OverflowTooltip\n key={`${template.id}-${appliedTemplateKey}`}\n content={template.title}\n forceShow\n placement=\"top\"\n className=\"block\"\n customContent={\n <div className=\"w-[320px] max-w-[calc(100vw-24px)] p-4\" data-template-preview-tooltip=\"1\">\n <h3 className=\"text-[14px] font-semibold text-[var(--text-primary)]\">{template.title}</h3>\n <div className=\"mt-3 min-h-0 max-h-[260px] overflow-y-auto\">\n <MarkdownContent\n content={buildTemplateMarkdown(template)}\n className=\"text-[12px] leading-[1.55] text-[var(--text-secondary)] [&_h2]:mb-3 [&_h2]:text-[14px] [&_h2]:font-semibold [&_h2]:text-[var(--text-primary)] [&_h3]:mb-2 [&_h3]:text-[12px] [&_h3]:font-semibold [&_h3]:text-[var(--text-primary)] [&_ul]:mb-3 [&_ul]:space-y-1.5\"\n disableCommandPrefix\n />\n </div>\n <div className=\"mt-4 flex justify-end\">\n <Button variant=\"major\" onClick={() => { onApplyTemplate(template.id); onAfterApplyTemplate?.(); }}>\n 插入模板\n </Button>\n </div>\n </div>\n }\n >\n <button\n type=\"button\"\n className=\"h-[98px] w-full rounded-[8px] border border-[var(--border-default)] bg-[var(--surface-panel)] px-4 py-4 text-left transition-[border-color,background-color,box-shadow] hover:border-[var(--card-hover-border)] hover:bg-[var(--card-hover-bg)] hover:shadow-[var(--card-hover-shadow)]\"\n >\n <div className=\"text-[14px] font-semibold text-[var(--text-primary)]\">{template.title}</div>\n <div className=\"mt-2 line-clamp-2 text-[12px] leading-5 text-[var(--text-muted)]\">{template.description}</div>\n </button>\n </OverflowTooltip>\n ))}\n </div>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n","import { useCallback, useRef, useState } from 'react';\nimport { MarkdownEditor } from './MarkdownEditor';\nimport { INSPIRATION_TEMPLATES, TEMPLATE_PAGE_SIZE, buildTemplateMarkdown } from '../constants';\n\ninterface MarkdownEditorWrapperProps {\n activeWorkingDraft: string;\n onDraftChange: (value: string) => void;\n}\n\nexport function MarkdownEditorWrapper({\n activeWorkingDraft,\n onDraftChange,\n}: MarkdownEditorWrapperProps) {\n const editorSurfaceRef = useRef<HTMLDivElement | null>(null);\n const editorTextareaRef = useRef<HTMLTextAreaElement | null>(null);\n\n const [templatePage, setTemplatePage] = useState(0);\n const [appliedTemplateKey, setAppliedTemplateKey] = useState(0);\n\n const templatePageCount = Math.max(1, Math.ceil(INSPIRATION_TEMPLATES.length / TEMPLATE_PAGE_SIZE));\n const visibleTemplates = INSPIRATION_TEMPLATES.slice(\n templatePage * TEMPLATE_PAGE_SIZE,\n templatePage * TEMPLATE_PAGE_SIZE + TEMPLATE_PAGE_SIZE,\n );\n\n const handleApplyTemplate = useCallback(\n (templateId: string) => {\n const template = INSPIRATION_TEMPLATES.find((t) => t.id === templateId);\n if (!template) return;\n\n const markdown = buildTemplateMarkdown(template);\n const existing = activeWorkingDraft.trim();\n onDraftChange(existing ? `${existing}\\n\\n${markdown}` : markdown);\n setAppliedTemplateKey((k) => k + 1);\n },\n [activeWorkingDraft, onDraftChange],\n );\n\n const handleAfterApplyTemplate = useCallback(() => {\n setAppliedTemplateKey((k) => k + 1);\n }, []);\n\n return (\n <MarkdownEditor\n activeTab=\"persona\"\n activeWorkingDraft={activeWorkingDraft}\n editorSurfaceRef={editorSurfaceRef}\n editorTextareaRef={editorTextareaRef}\n isPersonaEmpty={!activeWorkingDraft.trim()}\n onApplyTemplate={handleApplyTemplate}\n onAfterApplyTemplate={handleAfterApplyTemplate}\n onDraftChange={onDraftChange}\n onNextTemplatePage={() => setTemplatePage((p) => Math.min(templatePageCount - 1, p + 1))}\n onPrevTemplatePage={() => setTemplatePage((p) => Math.max(0, p - 1))}\n templatePage={templatePage}\n templatePageCount={templatePageCount}\n visibleTemplates={visibleTemplates}\n appliedTemplateKey={appliedTemplateKey}\n />\n );\n}\n","import { EmptyDataState } from '@/components/shared/EmptyDataState';\nimport { MarkdownContent } from '@/components/MarkdownContent';\nimport { MarkdownEditorWrapper } from './MarkdownEditorWrapper';\n\ninterface SoulConfigProps {\n personality?: string;\n agentId: string | null;\n readOnly?: boolean;\n muted?: boolean;\n onDraftChange?: (value: string) => void;\n showTitle?: boolean;\n}\n\nexport function SoulConfig({ personality, agentId, readOnly = false, muted = true, onDraftChange, showTitle = false }: SoulConfigProps) {\n if (!agentId) {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <EmptyDataState title=\"当前没有可展示的智能体\" />\n </div>\n );\n }\n\n const titleElement = showTitle ? <h2 className=\"mb-4 text-[16px] font-semibold text-[var(--text-primary)]\">灵魂配置</h2> : null;\n\n if (readOnly) {\n return (\n <div>\n {titleElement}\n <div className={`h-[480px] overflow-auto rounded-lg border border-[var(--border-default)] p-6${muted ? ' bg-[var(--surface-card-muted)]' : ''}`}>\n <MarkdownContent\n content={personality ?? ''}\n className={`max-w-none text-[14px] leading-7 ${muted ? 'text-[var(--text-secondary)] opacity-80' : 'text-[var(--text-primary)]'} [&_h1]:mb-4 [&_h1]:text-[18px] [&_h1]:font-bold ${muted ? '[&_h1]:text-[var(--text-secondary)]' : ''} [&_h2]:mb-3 [&_h2]:text-[16px] [&_h2]:font-semibold ${muted ? '[&_h2]:text-[var(--text-secondary)]' : ''} [&_h3]:mb-2 [&_h3]:text-[14px] [&_h3]:font-semibold ${muted ? '[&_h3]:text-[var(--text-secondary)]' : ''} [&_p]:mb-3 [&_ul]:mb-3 [&_ol]:mb-3 [&_li]:mb-1`}\n disableCommandPrefix\n />\n </div>\n </div>\n );\n }\n\n if (!personality?.trim()) {\n return (\n <div className=\"flex h-full min-h-0 flex-col items-center justify-center\">\n {titleElement}\n <div className=\"h-[480px] w-full rounded-lg border border-[var(--border-default)] p-6 text-center\">\n <EmptyDataState title=\"暂无内容\" />\n <p className=\"mt-1 text-[12px] text-[var(--text-secondary)]\">\n 请编辑灵魂配置内容,定义智能体的人格、行为准则与底线\n </p>\n </div>\n </div>\n );\n }\n\n if (!onDraftChange) {\n return (\n <div>\n {titleElement}\n <div className=\"h-[480px] overflow-auto rounded-lg border border-[var(--border-default)] p-6\">\n <MarkdownContent\n content={personality ?? ''}\n className=\"max-w-none text-[14px] leading-7 text-[var(--text-primary)] [&_h1]:mb-4 [&_h1]:text-[18px] [&_h1]:font-bold [&_h2]:mb-3 [&_h2]:text-[16px] [&_h2]:font-semibold [&_h3]:mb-2 [&_h3]:text-[14px] [&_h3]:font-semibold [&_p]:mb-3 [&_ul]:mb-3 [&_ol]:mb-3 [&_li]:mb-1\"\n disableCommandPrefix\n />\n </div>\n </div>\n );\n }\n\n return (\n <div>\n {titleElement}\n <MarkdownEditorWrapper\n activeWorkingDraft={personality}\n onDraftChange={onDraftChange}\n />\n </div>\n );\n}\n","import { API_URL } from '@/utils/api-client';\nimport type { AgentData } from '@/hooks/useAgentData';\nimport type { AgentCardData } from './types';\nimport { DEFAULT_PRESET_AVATAR, PRESET_AVATARS } from './constants';\n\nexport function agentToCardData(agent: AgentData): AgentCardData {\n return {\n id: agent.id,\n displayName: agent.displayName ?? agent.name ?? '未命名',\n avatar: agent.avatar,\n roleDescription: agent.roleDescription,\n defaultModel: agent.defaultModel,\n source: agent.source as 'runtime' | 'builtin',\n creationSource: agent.creationSource,\n };\n}\n\nexport type AgentSourceFilter = 'all' | 'seed' | 'runtime' | 'experts-plaza';\n\nexport function filterAgents(agents: AgentData[], searchQuery: string, sourceFilter: AgentSourceFilter = 'all'): AgentData[] {\n let result = agents;\n if (sourceFilter !== 'all') {\n result = result.filter((agent) => {\n if (sourceFilter === 'experts-plaza') return agent.creationSource === 'experts-plaza';\n if (sourceFilter === 'seed') return agent.source === 'seed';\n if (sourceFilter === 'runtime') return agent.source === 'runtime' && !agent.creationSource;\n return true;\n });\n }\n const normalizedQuery = searchQuery.trim().toLowerCase();\n if (!normalizedQuery) return result;\n return result.filter((agent) => agent.displayName?.toLowerCase().includes(normalizedQuery));\n}\n\nfunction avatarSeed(name: string): string {\n const normalized = name.trim() || 'BOT';\n let hash = 0;\n for (const char of normalized) {\n hash = (hash * 31 + char.charCodeAt(0)) % 360;\n }\n return `hsl(${hash} 72% 62%)`;\n}\n\nexport function buildGeneratedAvatarDataUrl(name: string): string {\n const label = (name.trim().slice(0, 1) || '智').toUpperCase();\n const color = avatarSeed(name);\n const svg = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"96\" height=\"96\" viewBox=\"0 0 96 96\">\n <defs>\n <linearGradient id=\"g\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"${color}\" />\n <stop offset=\"100%\" stop-color=\"#8AA4FF\" />\n </linearGradient>\n </defs>\n <rect width=\"96\" height=\"96\" rx=\"48\" fill=\"url(#g)\" />\n <circle cx=\"48\" cy=\"48\" r=\"38\" fill=\"rgba(255,255,255,0.18)\" />\n <text x=\"50%\" y=\"54%\" text-anchor=\"middle\" dominant-baseline=\"middle\" font-family=\"Inter, Arial, sans-serif\" font-size=\"38\" font-weight=\"700\" fill=\"#FFFFFF\">${label}</text>\n </svg>\n `.trim();\n return `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(svg)}`;\n}\n\nexport function resolveInitialAvatar(member: AgentData | null): string {\n return member?.avatar?.trim() ?? '';\n}\n\nexport function getRandomPresetAvatar(): string {\n const randomIndex = Math.floor(Math.random() * PRESET_AVATARS.length);\n return PRESET_AVATARS[randomIndex];\n}\n\nexport function formatAvatarUrl(avatar: string): string {\n return avatar.startsWith('/uploads/') ? `${API_URL}${avatar}` : avatar;\n}\n\nexport function isDuplicateNameErrorMessage(message: string | null | undefined): boolean {\n if (!message) return false;\n const normalized = message.trim().toLowerCase();\n if (!normalized) return false;\n return (\n (normalized.includes('名称') && normalized.includes('已被使用')) ||\n normalized.includes('duplicate') ||\n normalized.includes('already exists') ||\n normalized.includes('名称重复') ||\n normalized.includes('名字重复') ||\n normalized.includes('重名')\n );\n}\n","/*\n * *\n * * Copyright (C) Huawei Technologies Co., Ltd. 2026. All rights reserved.\n *\n */\n\nconst UNAVAILABLE_MODEL_ERROR_PATTERN = /model\\s+[\"'][^\"']+[\"']\\s+is not available on provider/i;\nconst MISSING_PROVIDER_ERROR_PATTERN = /provider\\s+[\"'][^\"']+[\"']\\s+not found/i;\n\nexport function normalizeAgentSaveErrorMessage(message: string | null | undefined): string | null {\n if (!message) return null;\n const trimmed = message.trim();\n if (!trimmed) return null;\n if (UNAVAILABLE_MODEL_ERROR_PATTERN.test(trimmed) || MISSING_PROVIDER_ERROR_PATTERN.test(trimmed)) {\n return '模型不存在,请重新选择';\n }\n return trimmed;\n}\n","/*\n * *\n * * Copyright (C) Huawei Technologies Co., Ltd. 2026. All rights reserved.\n *\n */\n\n'use client';\n\nimport { useMemo, useState } from 'react';\nimport { OverflowTooltip } from '@/components/shared/OverflowTooltip';\nimport { SearchInput } from '@/components/shared/SearchInput';\n\nconst DEFAULT_MODEL_ICON = '/avatars/assistant.svg';\n\nexport interface ModelOption {\n id: string;\n name: string;\n icon?: string;\n providerGroup?: string;\n experienceText?: string;\n statusText?: string;\n rightLabel?: string;\n}\n\nexport interface ModelOptionGroup {\n id: string;\n label: string;\n items: ModelOption[];\n}\n\ninterface ModelSelectDropdownProps {\n groups: ModelOptionGroup[];\n selectedId?: string | null;\n searchPlaceholder?: string;\n allowClear?: boolean;\n onSelect?: (item: ModelOption) => void;\n onClear?: () => void;\n}\n\ninterface ModelSelectValueProps {\n item?: ModelOption | null;\n placeholder?: string;\n loading?: boolean;\n}\n\nfunction ChevronDownIcon() {\n return (\n <svg className=\"h-4 w-4 text-[var(--text-muted)]\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M7 10L12 15L17 10\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction ModelIcon({ item }: { item: ModelOption }) {\n const imageSrc = item.icon?.trim() || DEFAULT_MODEL_ICON;\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={imageSrc}\n alt={`${item.name} icon`}\n data-testid={`model-logo-${item.name}`}\n className=\"h-[18px] w-[18px] shrink-0 object-contain\"\n />\n );\n}\n\nexport function ModelSelectValueDraft({\n item,\n placeholder = '请选择模型',\n loading = false,\n}: ModelSelectValueProps) {\n return (\n <span className=\"flex min-w-0 items-center gap-2.5\">\n {item && !loading ? <ModelIcon item={item} /> : null}\n <OverflowTooltip content={loading ? '加载模型中...' : (item?.name ?? placeholder)} className=\"min-w-0\">\n <span\n className={`block min-w-0 truncate text-[12px] ${item ? 'text-[var(--text-primary)]' : 'text-[var(--text-muted)]'}`}\n style={{\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n wordBreak: 'break-all',\n }}\n >\n {loading ? '加载模型中...' : (item?.name ?? placeholder)}\n </span>\n </OverflowTooltip>\n </span>\n );\n}\n\nexport function ModelSelectTriggerIcon() {\n return <ChevronDownIcon />;\n}\n\nexport function ModelSelectDropdown({\n groups,\n selectedId = null,\n searchPlaceholder = '输入关键字搜索',\n allowClear = false,\n onSelect,\n onClear,\n}: ModelSelectDropdownProps) {\n const [query, setQuery] = useState('');\n\n const filteredGroups = useMemo(() => {\n const normalized = query.trim().toLowerCase();\n if (!normalized) return groups;\n\n return groups\n .map((group) => ({\n ...group,\n items: group.items.filter((item) => {\n const haystack = [item.name, item.providerGroup, item.experienceText, item.statusText, item.rightLabel]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n return haystack.includes(normalized);\n }),\n }))\n .filter((group) => group.items.length > 0);\n }, [groups, query]);\n\n return (\n <div\n className=\"ui-panel flex max-h-[335px] w-full py-2 flex-col overflow-hidden rounded-[var(--radius-md)] bg-[var(--surface-panel)] shadow-[0_10px_24px_rgba(0,0,0,0.09)]\"\n data-testid=\"model-select-dropdown\"\n >\n <div className=\"px-4 py-1\">\n <SearchInput\n aria-label=\"搜索模型\"\n value={query}\n onChange={(value) => setQuery(value)}\n onClear={() => setQuery('')}\n placeholder={searchPlaceholder}\n wrapperClassName=\"w-full\"\n inputClassName=\"rounded-[var(--radius-pill)]\"\n />\n </div>\n <div aria-hidden=\"true\" className=\"my-[6px] h-px w-full bg-[var(--panel-border-outer)]\" />\n\n <div role=\"listbox\" className=\"flex min-h-0 flex-1 flex-col overflow-y-auto\">\n {allowClear && !query.trim() ? (\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={selectedId === null || selectedId === ''}\n data-testid=\"model-row-clear\"\n onClick={() => onClear?.()}\n className={`flex min-h-[34px] w-full items-center border-0 px-4 py-1.5 text-left transition-colors ${\n selectedId === null || selectedId === ''\n ? 'bg-[var(--menu-active-bg)] text-[var(--text-accent)]'\n : 'bg-[var(--surface-panel)] text-[var(--modal-text)] hover:bg-[var(--menu-hover-bg)] hover:text-[var(--text-accent)]'\n }`}\n >\n <div className=\"flex min-w-0 items-center gap-2.5\">\n <div className=\"h-[18px] w-[18px] shrink-0 rounded-full border border-dashed border-[var(--border-default)]\" />\n <div className=\"min-w-0\">\n <span className=\"block truncate text-[14px] leading-[20px] font-normal text-[var(--text-muted)]\">\n 不选择\n </span>\n </div>\n </div>\n </button>\n ) : null}\n {filteredGroups.map((group) => (\n <div key={group.id}>\n <div className=\"px-4 text-[12px] font-medium leading-[32px] text-[var(--text-label-secondary)]\">{group.label}</div>\n {group.items.map((item) => {\n const isSelected = item.id === selectedId;\n\n return (\n <button\n key={item.id}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n data-testid={`model-row-${item.id}`}\n onClick={() => onSelect?.(item)}\n className={`flex min-h-[34px] w-full items-center border-0 px-4 py-1.5 text-left transition-colors ${\n isSelected\n ? 'bg-[var(--menu-active-bg)] text-[var(--text-accent)]'\n : 'bg-[var(--surface-panel)] text-[var(--modal-text)] hover:bg-[var(--menu-hover-bg)] hover:text-[var(--text-accent)]'\n }`}\n >\n <div className=\"flex min-w-0 items-center gap-2.5\">\n <ModelIcon item={item} />\n <div className=\"min-w-0\">\n <OverflowTooltip content={item.name} className=\"w-full\">\n <div\n className=\"block min-w-0 truncate text-[14px] leading-[20px] font-normal text-current\"\n style={{\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n wordBreak: 'break-all',\n }}\n >\n {item.name}\n </div>\n </OverflowTooltip>\n </div>\n </div>\n </button>\n );\n })}\n </div>\n ))}\n\n {filteredGroups.length === 0 ? (\n <div className=\"px-3 py-6 text-center text-sm text-[var(--text-muted)]\">没有匹配的模型</div>\n ) : null}\n </div>\n </div>\n );\n}\n","import { createPortal } from 'react-dom';\nimport type { ChangeEvent, RefObject } from 'react';\nimport { MaskIcon } from '@/components/shared/MaskIcon';\nimport { Textarea } from '@/components/shared/Textarea';\nimport { HelpPrompt } from '@/components/shared/HelpPrompt';\nimport { ModelSelectDropdown, ModelSelectTriggerIcon, ModelSelectValueDraft } from './ModelSelectDropdown';\nimport type { CreateModelOption } from '../types';\nimport { formatAvatarUrl } from '../utils';\n\nfunction SparklesIcon() {\n return <MaskIcon name=\"random\" className=\"block h-[28px] w-[28px]\" />;\n}\n\ninterface BasicInfoSectionProps {\n avatarError: string | null;\n displayAvatar: string;\n draftDefaultModel: string;\n draftImageModel: string;\n draftDescription: string;\n draftName: string;\n fileInputRef: RefObject<HTMLInputElement>;\n inlineNameError: string | null;\n loadingModels: boolean;\n modelGroups: Array<{ id: string; label: string; items: CreateModelOption[] }>;\n modelMenuOpen: boolean;\n modelMenuPosition: { top: number; left: number; width: number } | null;\n modelMenuRef: RefObject<HTMLDivElement>;\n modelTriggerRef: RefObject<HTMLButtonElement>;\n modelError: string | null;\n loadingImageModels: boolean;\n imageModelGroups: Array<{ id: string; label: string; items: CreateModelOption[] }>;\n imageModelMenuOpen: boolean;\n imageModelMenuPosition: { top: number; left: number; width: number } | null;\n imageModelMenuRef: RefObject<HTMLDivElement>;\n imageModelTriggerRef: RefObject<HTMLButtonElement>;\n missingImageModel: boolean;\n onAvatarUpload: (event: ChangeEvent<HTMLInputElement>) => void;\n onDescriptionChange: (value: string) => void;\n onNameChange: (value: string) => void;\n onRandomAvatar: () => void;\n onSelectModel: (modelId: string) => void;\n onToggleModelMenu: () => void;\n onSelectImageModel: (modelId: string) => void;\n onClearImageModel: () => void;\n onToggleImageModelMenu: () => void;\n selectedModel: CreateModelOption | null;\n selectedImageModel: CreateModelOption | null;\n openAbove: boolean;\n imageModelOpenAbove: boolean;\n uploadingAvatar: boolean;\n}\n\nexport function BasicInfoSection({\n avatarError,\n displayAvatar,\n draftDefaultModel,\n draftImageModel,\n draftDescription,\n draftName,\n fileInputRef,\n inlineNameError,\n loadingModels,\n modelGroups,\n modelMenuOpen,\n modelMenuPosition,\n modelMenuRef,\n modelTriggerRef,\n modelError,\n loadingImageModels,\n imageModelGroups,\n imageModelMenuOpen,\n imageModelMenuPosition,\n imageModelMenuRef,\n imageModelTriggerRef,\n missingImageModel,\n onAvatarUpload,\n onDescriptionChange,\n onNameChange,\n onRandomAvatar,\n onSelectModel,\n onToggleModelMenu,\n onSelectImageModel,\n onClearImageModel,\n onToggleImageModelMenu,\n selectedModel,\n selectedImageModel,\n openAbove,\n imageModelOpenAbove,\n uploadingAvatar,\n}: BasicInfoSectionProps) {\n return (\n <div className=\"flex flex-col gap-4\">\n <h2 className=\"text-[16px] font-semibold text-[var(--text-primary)]\">基础信息</h2>\n\n <div className=\"flex flex-col gap-2\">\n <label className=\"text-[12px] text-[var(--text-primary)]\">名称</label>\n <input\n type=\"text\"\n value={draftName}\n onChange={(event) => onNameChange(event.target.value)}\n maxLength={64}\n className=\"ui-input h-[36px] w-full rounded-[6px] px-4 text-[14px]\"\n placeholder=\"请输入智能体名称\"\n />\n {inlineNameError ? <p className=\"text-[12px] text-[var(--state-error-text)]\">{inlineNameError}</p> : null}\n </div>\n\n <div className=\"flex flex-col gap-2\">\n <label className=\"text-[12px] text-[var(--text-primary)]\">描述(可选)</label>\n <Textarea\n value={draftDescription}\n onChange={(event) => onDescriptionChange(event.target.value)}\n placeholder=\"请输入描述\"\n maxLength={1000}\n showCount\n formatCount={(current, max) => `${current}/${max ?? 0}`}\n className=\"h-[80px] min-h-[80px] max-h-[160px] w-full overflow-y-auto text-[14px]\"\n />\n </div>\n\n <div className=\"flex flex-col gap-2\">\n <label className=\"text-[12px] text-[var(--text-primary)]\">图标</label>\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n className=\"group relative flex h-11 w-11 items-center justify-center rounded-full border border-transparent transition\"\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img src={formatAvatarUrl(displayAvatar)} alt=\"Avatar\" className=\"h-full w-full rounded-full object-cover\" />\n <span className=\"pointer-events-none absolute inset-0 flex items-center justify-center rounded-full bg-[var(--modal-loading-overlay)] opacity-0 transition group-hover:opacity-100\">\n <MaskIcon name=\"edit\" preserveOriginalColor className=\"h-4 w-4\" />\n </span>\n </button>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/jpg\"\n onChange={onAvatarUpload}\n className=\"hidden\"\n />\n <div className=\"h-11 pt-[22px]\">\n <div aria-hidden=\"true\" className=\"h-[16px] w-px bg-[var(--border-default)]\" />\n </div>\n <div className=\"h-11 pt-[16px]\">\n <button\n type=\"button\"\n onClick={onRandomAvatar}\n title=\"换一换\"\n className=\"h-[28px] w-[28px] min-h-[28px] min-w-[28px] rounded-[6px]\"\n >\n <SparklesIcon />\n </button>\n </div>\n </div>\n {avatarError ? <p className=\"text-[12px] text-[var(--state-error-text)]\">{avatarError}</p> : null}\n <p className=\"text-[12px] text-[var(--text-muted)]\">\n {uploadingAvatar ? '上传中...' : '支持 png、jpeg、jpg 格式,限制 200KB 内'}\n </p>\n </div>\n\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center gap-1.5\">\n <label className=\"text-[12px] text-[var(--text-primary)]\">主模型</label>\n <HelpPrompt tooltip=\"负责思考、推理、生成文本输出\" ariaLabel=\"主模型说明\" />\n </div>\n {modelGroups.length > 0 || selectedModel ? (\n <>\n <button\n ref={modelTriggerRef}\n type=\"button\"\n aria-label=\"Model\"\n aria-haspopup=\"listbox\"\n aria-expanded={modelMenuOpen}\n aria-invalid={Boolean(modelError)}\n onClick={onToggleModelMenu}\n className=\"ui-field flex h-[28px] w-full items-center justify-between rounded-[6px] bg-[var(--surface-panel)] px-[10px] text-left text-[12px]\"\n >\n <ModelSelectValueDraft item={selectedModel} loading={loadingModels} />\n <ModelSelectTriggerIcon />\n </button>\n {modelError ? <p className=\"text-[12px] text-[var(--state-error-text)]\">{modelError}</p> : null}\n\n {modelMenuOpen && modelMenuPosition\n ? createPortal(\n <div\n ref={modelMenuRef}\n className=\"fixed z-[70]\"\n style={{\n top: modelMenuPosition.top,\n left: modelMenuPosition.left,\n width: modelMenuPosition.width,\n transform: openAbove ? 'translateY(-100%)' : undefined,\n }}\n >\n <ModelSelectDropdown\n groups={modelGroups}\n selectedId={selectedModel?.id ?? draftDefaultModel}\n onSelect={(item) => onSelectModel(item.id)}\n />\n </div>,\n document.body,\n )\n : null}\n </>\n ) : (\n <div className=\"ui-field flex h-[28px] w-full items-center rounded-[6px] px-4 text-[12px] text-[var(--text-muted)]\">\n {loadingModels ? '加载模型中...' : '暂无可用模型'}\n </div>\n )}\n </div>\n\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center gap-1.5\">\n <label className=\"text-[12px] text-[var(--text-primary)]\">图像理解模型(可选)</label>\n <HelpPrompt tooltip=\"用于对图片内容的识别场景,对图片附件进行处理\" ariaLabel=\"图像理解模型说明\" />\n </div>\n {imageModelGroups.length > 0 || selectedImageModel ? (\n <>\n <button\n ref={imageModelTriggerRef}\n type=\"button\"\n aria-label=\"Image Model\"\n aria-haspopup=\"listbox\"\n aria-expanded={imageModelMenuOpen}\n onClick={onToggleImageModelMenu}\n className=\"ui-field flex h-[28px] w-full items-center justify-between rounded-[6px] bg-[var(--surface-panel)] px-[10px] text-left text-[12px]\"\n >\n <ModelSelectValueDraft item={selectedImageModel} loading={loadingImageModels} placeholder=\"请选择图像理解模型(可选)\" />\n <ModelSelectTriggerIcon />\n </button>\n\n {imageModelMenuOpen && imageModelMenuPosition\n ? createPortal(\n <div\n ref={imageModelMenuRef}\n className=\"fixed z-[70]\"\n style={{\n top: imageModelMenuPosition.top,\n left: imageModelMenuPosition.left,\n width: imageModelMenuPosition.width,\n transform: imageModelOpenAbove ? 'translateY(-100%)' : undefined,\n }}\n >\n <ModelSelectDropdown\n groups={imageModelGroups}\n selectedId={selectedImageModel?.id ?? draftImageModel}\n allowClear\n onSelect={(item) => onSelectImageModel(item.id)}\n onClear={onClearImageModel}\n />\n </div>,\n document.body,\n )\n : null}\n </>\n ) : (\n <div className=\"ui-field flex h-[28px] w-full items-center rounded-[6px] px-4 text-[12px] text-[var(--text-muted)]\">\n {loadingImageModels ? '加载模型中...' : '暂无可用模型'}\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { Button } from '@/components/shared/Button';\n\ninterface FormFooterProps {\n error: string | null;\n formMode: 'create' | 'edit';\n isConfirmDisabled: boolean;\n onCancel: () => void;\n onSave: () => void;\n saving: boolean;\n}\n\nexport function FormFooter({ error, formMode, isConfirmDisabled, onCancel, onSave, saving }: FormFooterProps) {\n return (\n <div className=\"flex flex-col gap-3 border-t border-[var(--panel-divider)] bg-[var(--surface-panel)] px-8 py-4\">\n {error ? (\n <div className=\"rounded-[var(--radius-md)] bg-[var(--state-error-bg)] px-4 py-[6px] text-[14px] text-[var(--state-error-text)]\">\n {error}\n </div>\n ) : null}\n <div className=\"flex items-center justify-end gap-3\">\n <Button variant=\"default\" onClick={onCancel}>\n 取消\n </Button>\n <Button variant=\"major\" onClick={onSave} disabled={isConfirmDisabled}>\n {saving ? (formMode === 'edit' ? '保存中...' : '创建中...') : formMode === 'edit' ? '保存' : '创建'}\n </Button>\n </div>\n </div>\n );\n}","import { useState } from 'react';\nimport { Alert } from '@/components/shared/Alert';\n\ninterface FormHeaderProps {\n displayName: string;\n formMode: 'create' | 'edit';\n onBackToDetail: () => void;\n onBackToList: () => void;\n}\n\nexport function FormHeader({ displayName, formMode, onBackToDetail, onBackToList }: FormHeaderProps) {\n const [showWarning, setShowWarning] = useState(true);\n\n if (formMode === 'create') {\n return (\n <>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={onBackToList}\n className=\"text-[12px] text-[var(--text-secondary)] transition hover:text-[var(--text-primary)]\"\n >\n 智能体管理\n </button>\n <span className=\"text-[12px] text-[var(--text-muted)]\">/</span>\n <span className=\"text-[12px] font-bold text-[var(--text-primary)]\">创建智能体</span>\n </div>\n <h2 className=\"text-[18px] font-bold text-[var(--text-primary)] mt-2\">创建智能体</h2>\n </>\n );\n }\n\n return (\n <>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={onBackToList}\n className=\"text-[12px] text-[var(--text-secondary)] transition hover:text-[var(--text-primary)]\"\n >\n 智能体管理\n </button>\n <span className=\"text-[12px] text-[var(--text-muted)]\">/</span>\n <button\n type=\"button\"\n onClick={onBackToDetail}\n className=\"text-[12px] text-[var(--text-primary)] transition hover:text-[var(--accent-primary)]\"\n >\n {displayName}\n </button>\n <span className=\"text-[12px] text-[var(--text-muted)]\">/</span>\n <span className=\"text-[12px] font-bold text-[var(--text-primary)]\">编辑智能体</span>\n </div>\n <h2 className=\"text-[18px] font-bold text-[var(--text-primary)] mt-2\">编辑智能体</h2>\n {showWarning && (\n <div className=\"mt-3\">\n <Alert mode=\"prompt\" closable onClose={() => setShowWarning(false)}>\n 若智能体正在执行任务中,建议暂时不要编辑以免影响任务执行\n </Alert>\n </div>\n )}\n </>\n );\n}\n","import { useCallback, useRef, useState } from 'react';\n\ntype InstallStatusValue = string | null; // 'installing' | 'error' | null\n\ninterface UseInstallStatusResult {\n installStatus: Map<string, string>;\n setInstallStatusWithTimer: (slug: string, status: string) => void;\n clearInstallStatus: (slug: string) => void;\n}\n\nexport function useInstallStatus(): UseInstallStatusResult {\n const [installStatus, setInstallStatus] = useState<Map<string, string>>(new Map());\n const statusTimers = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());\n\n const setInstallStatusWithTimer = useCallback(\n (slug: string, status: string) => {\n setInstallStatus((prev) => new Map(prev).set(slug, status));\n const existing = statusTimers.current.get(slug);\n if (existing) clearTimeout(existing);\n if (typeof status === 'string' && status !== 'installing') {\n const timer = setTimeout(() => {\n setInstallStatus((prev) => {\n const next = new Map(prev);\n next.delete(slug);\n return next;\n });\n statusTimers.current.delete(slug);\n }, 3000);\n statusTimers.current.set(slug, timer);\n }\n },\n [],\n );\n\n const clearInstallStatus = useCallback((slug: string) => {\n setInstallStatus((prev) => {\n const next = new Map(prev);\n next.delete(slug);\n return next;\n });\n const existing = statusTimers.current.get(slug);\n if (existing) {\n clearTimeout(existing);\n statusTimers.current.delete(slug);\n }\n }, []);\n\n return { installStatus, setInstallStatusWithTimer, clearInstallStatus };\n}","import { useCallback, useRef, useState } from 'react';\nimport type React from 'react';\nimport { apiFetch } from '@/utils/api-client';\n\nconst PAGE_SIZE = 24;\n\nconst CATEGORY_MAP: Record<string, string> = {\n 'ai-intelligence': 'AI 智能',\n 'developer-tools': '开发工具',\n productivity: '效率提升',\n 'content-creation': '内容创作',\n 'data-analysis': '数据分析',\n 'security-compliance': '安全合规',\n 'communication-collaboration': '沟通协作',\n};\n\nfunction normalizeCategory(cat: string): string {\n return CATEGORY_MAP[cat] ?? cat;\n}\n\nfunction resolveCategoryParam(category: string): string | null {\n if (!category || category === '全部') return null;\n return Object.entries(CATEGORY_MAP).find(([, zh]) => zh === category)?.[0] ?? category;\n}\n\ninterface SearchSkill {\n id: string;\n slug: string;\n name: string;\n description: string;\n version?: string;\n category?: string;\n tags: string[];\n stars?: number;\n repo: { githubOwner: string; githubRepoName: string };\n isInstalled: boolean;\n}\n\ninterface SearchResult {\n skills: SearchSkill[];\n total: number;\n page: number;\n hasMore: boolean;\n}\n\ninterface UseSkillSearchResult {\n searchResults: SearchResult | null;\n setSearchResults: React.Dispatch<React.SetStateAction<SearchResult | null>>;\n searchLoading: boolean;\n loadingMore: boolean;\n currentPage: number;\n categories: string[];\n activeCategory: string;\n loadPage: (opts: { page: number; append?: boolean; category?: string }) => Promise<void>;\n loadCategories: () => Promise<void>;\n handleLoadMore: () => void;\n setActiveCategory: (category: string) => void;\n}\n\nexport function useSkillSearch(): UseSkillSearchResult {\n const [searchResults, setSearchResults] = useState<SearchResult | null>(null);\n const [searchLoading, setSearchLoading] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n const [currentPage, setCurrentPage] = useState(1);\n const [categories, setCategories] = useState<string[]>([]);\n const [activeCategory, setActiveCategory] = useState('全部');\n\n const requestSeqRef = useRef(0);\n const activeAbortRef = useRef<AbortController | null>(null);\n\n const buildSkillsUrl = useCallback((page: number, category: string) => {\n const params = new URLSearchParams({ page: String(page), limit: String(PAGE_SIZE) });\n const categoryParam = resolveCategoryParam(category);\n if (categoryParam) {\n params.set('category', categoryParam);\n }\n return `/api/skills/all?${params.toString()}`;\n }, []);\n\n const loadPage = useCallback(\n async ({\n page,\n append = false,\n category = '全部',\n }: {\n page: number;\n append?: boolean;\n category?: string;\n }) => {\n const requestId = ++requestSeqRef.current;\n activeAbortRef.current?.abort();\n const controller = new AbortController();\n activeAbortRef.current = controller;\n\n const setLoadingFn = append ? setLoadingMore : setSearchLoading;\n setLoadingFn(true);\n\n try {\n const res = await apiFetch(buildSkillsUrl(page, category ?? '全部'), { signal: controller.signal });\n if (!res.ok) return;\n const data = (await res.json()) as SearchResult;\n if (requestId !== requestSeqRef.current) return;\n\n setSearchResults((prev) => {\n if (!append || !prev) return data;\n return {\n ...data,\n skills: [...prev.skills, ...data.skills],\n };\n });\n setCurrentPage(page);\n } catch (error) {\n if (error instanceof DOMException && error.name === 'AbortError') return;\n } finally {\n if (requestId === requestSeqRef.current) {\n setLoadingFn(false);\n }\n }\n },\n [buildSkillsUrl],\n );\n\n const loadCategories = useCallback(async () => {\n try {\n const res = await apiFetch('/api/skills/categories');\n if (res.ok) {\n const data = (await res.json()) as { categories: string[] };\n const sorted = [...new Set(data.categories)].sort((left, right) =>\n left.localeCompare(right, 'zh-CN'),\n );\n setCategories(sorted.map(normalizeCategory));\n }\n } catch {\n // ignore error\n }\n }, []);\n\n const handleLoadMore = useCallback(() => {\n if (loadingMore || !searchResults?.hasMore) return;\n void loadPage({ page: currentPage + 1, append: true, category: activeCategory });\n }, [loadingMore, searchResults?.hasMore, currentPage, loadPage, activeCategory]);\n\n return {\n searchResults,\n setSearchResults,\n searchLoading,\n loadingMore,\n currentPage,\n categories,\n activeCategory,\n loadPage,\n loadCategories,\n handleLoadMore,\n setActiveCategory,\n };\n}\n\nexport { normalizeCategory, resolveCategoryParam };\nexport type { SearchSkill };","import { useCallback } from 'react';\nimport { apiFetch } from '@/utils/api-client';\nimport { notifySkillOptionsChanged } from '@/utils/skill-options-cache';\nimport { useToastStore } from '@/stores/toastStore';\n\ninterface UseSkillInstallOptions {\n onInstallSuccess?: (skill: string) => void;\n onInstallError?: (skill: string, error: string) => void;\n}\n\ninterface UseSkillInstallResult {\n handleInstall: (\n owner: string,\n repo: string,\n skill: string,\n skillDescription: string,\n skillVersion: string,\n ) => Promise<void>;\n}\n\nexport function useSkillInstall({\n onInstallSuccess,\n onInstallError,\n}: UseSkillInstallOptions = {}): UseSkillInstallResult {\n const handleInstall = useCallback(\n async (\n owner: string,\n repo: string,\n skill: string,\n skillDescription: string,\n skillVersion: string,\n ) => {\n try {\n const res = await apiFetch('/api/skills/install', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n owner,\n repo,\n skill,\n description: skillDescription,\n version: skillVersion,\n }),\n });\n if (res.ok) {\n notifySkillOptionsChanged();\n useToastStore.getState().addToast({\n type: 'success',\n title: '安装成功',\n message: `\"${skill}\" 安装成功,可在我的技能中查看`,\n duration: 4000,\n });\n onInstallSuccess?.(skill);\n } else {\n const payload = (await res.json().catch(() => ({}))) as { error?: string };\n const detail = payload.error ?? `HTTP ${res.status}`;\n useToastStore.getState().addToast({\n type: 'error',\n title: '安装失败',\n message: detail,\n duration: 4000,\n });\n onInstallError?.(skill, detail);\n }\n } catch {\n useToastStore.getState().addToast({\n type: 'error',\n title: '安装失败',\n message: '网络错误,请重试',\n duration: 4000,\n });\n onInstallError?.(skill, '网络错误,请重试');\n }\n },\n [onInstallSuccess, onInstallError],\n );\n\n return { handleInstall };\n}","/*\n * *\n * * Copyright (C) Huawei Technologies Co., Ltd. 2026. All rights reserved.\n *\n */\n\n'use client';\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { Button } from '@/components/shared/Button';\nimport { apiFetch } from '@/utils/api-client';\nimport { SearchInput } from '@/components/shared/SearchInput';\nimport { NameInitialIcon } from '@/components/NameInitialIcon';\nimport { OverflowTooltip } from '@/components/shared/OverflowTooltip';\nimport { setMultipleSkillBasicInfos, type SkillBasicInfo } from './skill-basic-info-cache';\nimport { useInstallStatus } from '../hooks/useInstallStatus';\nimport { useSkillSearch, normalizeCategory, type SearchSkill } from '../hooks/useSkillSearch';\nimport { useSkillInstall } from '../hooks/useSkillInstall';\nimport { UploadSkillModal } from '@/components/skills-panel/components/UploadSkillModal';\nimport styles from './SkillSelectorDrawer.module.css';\n\nexport interface SkillInfo {\n id: string;\n name: string;\n description: string;\n category?: string;\n trigger?: string | string[];\n source?: 'builtin' | 'external';\n}\n\ninterface SkillSelectorDrawerProps {\n open: boolean;\n selectedSkills: string[];\n skillBasicInfos?: Map<string, SkillBasicInfo>;\n onConfirm: (skills: string[], skillBasicInfos?: Map<string, SkillBasicInfo>) => void;\n onClose: () => void;\n}\n\ntype ViewMode = 'installed' | 'plaza';\n\nconst INSTALLED_TAB = '我的技能';\nconst SKILL_PLAZA_TAB = '技能广场';\nconst ALL_CATEGORY = '全部';\nconst UNCATEGORIZED = '其他';\n\nconst ALL_SKILL_SOURCES = 'all';\ntype SkillSourceScope = 'builtin' | 'external' | typeof ALL_SKILL_SOURCES;\nconst SKILL_SCOPE_TABS: readonly { id: SkillSourceScope; label: string }[] = [\n { id: ALL_SKILL_SOURCES, label: '全部' },\n { id: 'external', label: '我添加的' },\n { id: 'builtin', label: '平台精选' },\n];\n\nconst CATEGORY_FILTER_ARIA_LABEL = '筛选分类';\n\nfunction skillMatchesQuery(skill: SkillInfo, query: string): boolean {\n const lowered = query.toLowerCase();\n return (\n skill.id.toLowerCase().includes(lowered) ||\n skill.name.toLowerCase().includes(lowered) ||\n skill.description.toLowerCase().includes(lowered)\n );\n}\n\ninterface SkillsResponse {\n skills: Array<{\n name: string;\n description?: string;\n category?: string;\n trigger?: string | string[];\n source?: 'local' | 'skillhub';\n }>;\n}\n\nfunction markSkillInstalled(\n slug: string,\n setSearchResults: (fn: (prev: { skills: SearchSkill[]; total: number; page: number; hasMore: boolean } | null) => { skills: SearchSkill[]; total: number; page: number; hasMore: boolean } | null) => void,\n) {\n setSearchResults((prev) => {\n if (!prev) return prev;\n let changed = false;\n const skills = prev.skills.map((item) => {\n if (item.slug !== slug || item.isInstalled) return item;\n changed = true;\n return { ...item, isInstalled: true };\n });\n return changed ? { ...prev, skills } : prev;\n });\n}\n\nexport function SkillSelectorDrawer({\n open,\n selectedSkills,\n skillBasicInfos,\n onConfirm,\n onClose,\n}: SkillSelectorDrawerProps) {\n const [activeTab, setActiveTab] = useState<ViewMode>('installed');\n const [query, setQuery] = useState('');\n const [draftSelected, setDraftSelected] = useState<string[]>([]);\n const [skills, setSkills] = useState<SkillInfo[]>([]);\n const [internalSkillBasicInfos, setInternalSkillBasicInfos] = useState<Map<string, SkillBasicInfo>>(new Map());\n const [loading, setLoading] = useState(false);\n\n const [activeSourceScope, setActiveSourceScope] = useState<SkillSourceScope>(ALL_SKILL_SOURCES);\n const [categoryMenuOpen, setCategoryMenuOpen] = useState(false);\n const [uploadModalOpen, setUploadModalOpen] = useState(false);\n const categoryMenuRef = useRef<HTMLDivElement>(null);\n const searchEffectReadyRef = useRef(false);\n const loadMoreTriggerRef = useRef<HTMLDivElement>(null);\n\n const { installStatus, setInstallStatusWithTimer, clearInstallStatus } = useInstallStatus();\n const { searchResults, setSearchResults, searchLoading, loadingMore, loadPage, loadCategories, handleLoadMore, activeCategory, setActiveCategory, categories } =\n useSkillSearch();\n const { handleInstall } = useSkillInstall();\n\n useEffect(() => {\n if (!open) return;\n setDraftSelected(selectedSkills);\n setQuery('');\n setLoading(true);\n apiFetch('/api/skills')\n .then((res) => (res.ok ? res.json() : null))\n .then((data: SkillsResponse | null) => {\n if (data?.skills) {\n const skillInfoList = data.skills.map((s) => ({\n id: s.name,\n name: s.name,\n description: typeof s.description === 'string' ? s.description : '',\n category: s.category,\n trigger: s.trigger,\n source: (s.source === 'skillhub' ? 'external' : 'builtin') as 'builtin' | 'external',\n }));\n setSkills(skillInfoList);\n const detailsMap = new Map<string, SkillBasicInfo>();\n data.skills.forEach((s) => {\n detailsMap.set(s.name, { name: s.name, description: s.description });\n });\n setInternalSkillBasicInfos(detailsMap);\n setMultipleSkillBasicInfos(Array.from(detailsMap.values()));\n }\n })\n .finally(() => setLoading(false));\n }, [open, selectedSkills]);\n\n useEffect(() => {\n if (activeTab === 'plaza') {\n void loadCategories();\n void loadPage({ page: 1, category: ALL_CATEGORY });\n }\n }, [activeTab, loadCategories, loadPage]);\n\n useEffect(() => {\n if (!searchEffectReadyRef.current) {\n searchEffectReadyRef.current = true;\n return;\n }\n\n if (activeTab !== 'plaza') return;\n if (!query.trim()) return;\n\n const timer = setTimeout(() => {\n setActiveCategory(ALL_CATEGORY);\n void loadPage({ page: 1, category: ALL_CATEGORY });\n }, 300);\n\n return () => clearTimeout(timer);\n }, [query, activeTab, loadPage, setActiveCategory]);\n\n const handleCategoryChange = useCallback(\n (category: string) => {\n setQuery('');\n setActiveCategory(category);\n void loadPage({ page: 1, category });\n },\n [loadPage, setActiveCategory],\n );\n\n const handleUploadSuccess = useCallback(() => {\n setUploadModalOpen(false);\n apiFetch('/api/skills')\n .then((res) => (res.ok ? res.json() : null))\n .then((data: SkillsResponse | null) => {\n if (data?.skills) {\n const skillInfoList = data.skills.map((s) => ({\n id: s.name,\n name: s.name,\n description: typeof s.description === 'string' ? s.description : '',\n category: s.category,\n trigger: s.trigger,\n source: (s.source === 'skillhub' ? 'external' : 'builtin') as 'builtin' | 'external',\n }));\n setSkills(skillInfoList);\n const detailsMap = new Map<string, SkillBasicInfo>();\n data.skills.forEach((s) => {\n detailsMap.set(s.name, { name: s.name, description: s.description });\n });\n setInternalSkillBasicInfos(detailsMap);\n setMultipleSkillBasicInfos(Array.from(detailsMap.values()));\n }\n });\n }, []);\n\n useEffect(() => {\n const el = loadMoreTriggerRef.current;\n if (!el || !searchResults?.hasMore || loadingMore) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries[0].isIntersecting) {\n handleLoadMore();\n }\n },\n { rootMargin: '200px' },\n );\n\n observer.observe(el);\n return () => observer.disconnect();\n }, [searchResults?.hasMore, loadingMore, handleLoadMore]);\n\n useEffect(() => {\n if (!open) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose();\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [onClose, open]);\n\n useEffect(() => {\n if (!categoryMenuOpen) return;\n const onPointerDown = (event: MouseEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (categoryMenuRef.current?.contains(target)) return;\n setCategoryMenuOpen(false);\n };\n document.addEventListener('mousedown', onPointerDown);\n return () => document.removeEventListener('mousedown', onPointerDown);\n }, [categoryMenuOpen]);\n\n const filteredSkills = useMemo(() => {\n if (activeTab === 'plaza') return [];\n let filtered = skills;\n if (activeSourceScope !== ALL_SKILL_SOURCES) {\n filtered = filtered.filter((skill) => skill.source === activeSourceScope);\n }\n if (activeCategory !== ALL_CATEGORY) {\n filtered = filtered.filter((skill) => (skill.category?.trim() || UNCATEGORIZED) === activeCategory);\n }\n const normalized = query.trim().toLowerCase();\n if (!normalized) return filtered;\n return filtered.filter((skill) => skillMatchesQuery(skill, normalized));\n }, [activeTab, query, skills, activeSourceScope, activeCategory]);\n\n const installedCategories = useMemo(() => {\n const cats = new Set<string>();\n for (const skill of skills) {\n if (activeSourceScope !== ALL_SKILL_SOURCES && skill.source !== activeSourceScope) continue;\n cats.add(skill.category?.trim() || UNCATEGORIZED);\n }\n return Array.from(cats).sort();\n }, [skills, activeSourceScope]);\n\n const plazaSkills = useMemo(() => {\n if (activeTab !== 'plaza') return [];\n return searchResults?.skills ?? [];\n }, [activeTab, searchResults]);\n\n const toggleSkill = useCallback((skillId: string) => {\n setDraftSelected((prev) => {\n if (prev.includes(skillId)) {\n return prev.filter((id) => id !== skillId);\n }\n return [...prev, skillId];\n });\n }, []);\n\n const handleConfirm = useCallback(() => {\n const allSkillInfos = new Map([...(skillBasicInfos ?? new Map()), ...internalSkillBasicInfos]);\n onConfirm(draftSelected, allSkillInfos);\n }, [draftSelected, skillBasicInfos, internalSkillBasicInfos, onConfirm]);\n\n const onInstallSkill = useCallback(\n async (owner: string, repo: string, skill: string, skillDescription: string, skillVersion: string) => {\n setInstallStatusWithTimer(skill, 'installing');\n await handleInstall(owner, repo, skill, skillDescription, skillVersion);\n clearInstallStatus(skill);\n markSkillInstalled(skill, setSearchResults);\n },\n [handleInstall, setInstallStatusWithTimer, clearInstallStatus],\n );\n\n if (!open) return null;\n\n const displaySkills = activeTab === 'installed' ? filteredSkills : plazaSkills;\n const isLoading = activeTab === 'installed' ? loading : searchLoading;\n const hasResults = displaySkills.length > 0;\n\n return (\n <div className={styles.backdrop} data-testid=\"skill-selector-drawer\">\n <div className={styles.drawer}>\n <div className={styles.header}>\n <h2 className={styles.title}>选择技能</h2>\n <button\n type=\"button\"\n onClick={onClose}\n className={styles.closeButton}\n aria-label=\"关闭技能选择\"\n >\n <svg className=\"h-[18px] w-[18px]\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M6 6L18 18\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" />\n <path d=\"M18 6L6 18\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n\n <div className={styles.body}>\n <div className={styles.tabsWrapper}>\n <div className={styles.tabs}>\n <button\n type=\"button\"\n onClick={() => setActiveTab('installed')}\n className={`${styles.tab} ${activeTab === 'installed' ? styles.tabActive : ''}`}\n >\n {INSTALLED_TAB}\n </button>\n <button\n type=\"button\"\n onClick={() => setActiveTab('plaza')}\n className={`${styles.tab} ${activeTab === 'plaza' ? styles.tabActive : ''}`}\n >\n {SKILL_PLAZA_TAB}\n </button>\n </div>\n </div>\n\n {activeTab === 'installed' && (\n <div className={styles.categoriesWrapper}>\n <div className={styles.categories}>\n {SKILL_SCOPE_TABS.map((tab, index) => (\n <div key={tab.id} className={styles.categoryItem}>\n {index > 0 ? <div aria-hidden=\"true\" className={styles.categoryDivider} /> : null}\n <button\n type=\"button\"\n onClick={() => setActiveSourceScope(tab.id)}\n className={`${styles.categoryTab} ${activeSourceScope === tab.id ? styles.categoryTabActive : ''}`}\n >\n {tab.label}\n </button>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {activeTab === 'plaza' && categories.length > 0 && (\n <div className={styles.categoriesWrapper}>\n <div className={styles.categories}>\n {[ALL_CATEGORY, ...categories].map((category, index) => (\n <div key={category} className={styles.categoryItem}>\n {index > 0 ? <div aria-hidden=\"true\" className={styles.categoryDivider} /> : null}\n <button\n type=\"button\"\n onClick={() => handleCategoryChange(category)}\n className={`${styles.categoryTab} ${activeCategory === category ? styles.categoryTabActive : ''}`}\n >\n {category}\n </button>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {activeTab === 'installed' && (\n <div className={styles.categoriesWrapper}>\n <Button variant=\"default\" onClick={() => setUploadModalOpen(true)}>\n 导入技能\n </Button>\n </div>\n )}\n\n <div className={styles.searchWrapper}>\n {activeTab === 'installed' && installedCategories.length > 0 && (\n <div ref={categoryMenuRef} className=\"relative w-[200px] shrink-0\">\n <select\n aria-label={CATEGORY_FILTER_ARIA_LABEL}\n value={activeCategory}\n onChange={(event) => handleCategoryChange(event.target.value)}\n className=\"sr-only\"\n tabIndex={-1}\n >\n {[ALL_CATEGORY, ...installedCategories].map((cat) => (\n <option key={cat} value={cat}>{cat}</option>\n ))}\n </select>\n <button\n type=\"button\"\n onClick={() => setCategoryMenuOpen((prev) => !prev)}\n className={`ui-field flex h-[28px] w-[200px] items-center justify-between rounded-[6px] px-[12px] py-[5px] text-xs transition-colors ${categoryMenuOpen ? 'border-[#191919]' : ''}`}\n aria-haspopup=\"listbox\"\n aria-expanded={categoryMenuOpen}\n >\n <span className=\"truncate text-[var(--text-primary)]\">{activeCategory}</span>\n <svg\n className={`h-3.5 w-3.5 text-[var(--text-muted)] transition-transform duration-200 ${categoryMenuOpen ? 'rotate-180' : ''}`}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path d=\"M4 6L8 10L12 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n {categoryMenuOpen && (\n <div\n role=\"listbox\"\n className=\"absolute left-0 top-[calc(100%+4px)] z-30 w-[200px] rounded-[6px] bg-[var(--surface-panel)] py-[8px] shadow-[0_2px_12px_0_var(--tooltip-shadow-color)]\"\n >\n {[ALL_CATEGORY, ...installedCategories].map((cat) => {\n const isSelected = cat === activeCategory;\n return (\n <button\n key={cat}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => {\n handleCategoryChange(cat);\n setCategoryMenuOpen(false);\n }}\n className={`flex h-[32px] w-full items-center px-[16px] py-[7px] text-left text-xs transition-colors hover:bg-[var(--tag-bg)] ${isSelected ? 'text-[var(--text-accent)]' : 'text-[var(--text-primary)]'}`}\n >\n {cat}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n <SearchInput\n wrapperClassName=\"w-full\"\n value={query}\n onChange={(value: string) => setQuery(value)}\n placeholder={activeTab === 'installed' ? '输入关键字搜索技能' : '搜索技能广场'}\n aria-label=\"搜索技能\"\n data-testid=\"skill-search-input\"\n />\n </div>\n\n <div className={styles.content}>\n {isLoading ? (\n <div className={styles.emptyState}>加载中...</div>\n ) : !hasResults ? (\n <div className={styles.emptyState}>没有匹配到技能</div>\n ) : (\n <>\n <div className={styles.skillGrid}>\n {displaySkills.map((skill) => {\n const skillId = activeTab === 'installed' ? (skill as SkillInfo).id : (skill as SearchSkill).slug;\n const skillName = activeTab === 'installed' ? (skill as SkillInfo).name : (skill as SearchSkill).name;\n const skillDesc =\n activeTab === 'installed'\n ? (skill as SkillInfo).description\n : (skill as SearchSkill).description;\n const skillCategory =\n activeTab === 'installed'\n ? (skill as SkillInfo).category\n : normalizeCategory((skill as SearchSkill).category ?? '');\n const isSelected = draftSelected.includes(skillId);\n const isInstalled = activeTab === 'plaza' ? (skill as SearchSkill).isInstalled : false;\n return (\n <article\n key={skillId}\n className={`${styles.card} ${isSelected ? styles.cardSelected : ''}`}\n onClick={() => {\n if (activeTab === 'plaza' && !isInstalled) return;\n toggleSkill(skillId);\n }}\n >\n <div className={styles.cardHeader}>\n <NameInitialIcon name={skillName || skillId} />\n <div className={styles.cardContent}>\n <OverflowTooltip\n content={skillName}\n className=\"min-w-0\"\n as=\"h3\"\n textClassName={`${styles.cardTitle} block truncate`}\n />\n <div className=\"mt-1 flex flex-wrap items-center gap-2 leading-[18px] text-xs\">\n {skillCategory && <span className={styles.badge}>{skillCategory}</span>}\n </div>\n </div>\n {activeTab === 'plaza' && !isInstalled ? null : (\n <div className={`${styles.checkbox} ${isSelected ? styles.checkboxChecked : ''}`}>\n {isSelected ? (\n <svg className=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fillRule=\"evenodd\"\n d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n ) : (\n <svg className=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"14\" height=\"14\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </svg>\n )}\n </div>\n )}\n </div>\n\n <OverflowTooltip content={skillDesc || '暂未提供技能描述。'} className=\"w-full\">\n <p className={styles.cardDescription}>{skillDesc || '暂未提供技能描述。'}</p>\n </OverflowTooltip>\n\n {activeTab === 'plaza' && (\n <div className={styles.cardFooter}>\n {isInstalled ? (\n <span className=\"shrink-0 text-xs\" style={{ color: 'var(--text-disabled)' }}>\n 已安装\n </span>\n ) : (skill as SearchSkill).repo.githubOwner && (skill as SearchSkill).repo.githubRepoName ? (\n <button\n type=\"button\"\n className={styles.installButton}\n onClick={(e) => {\n e.stopPropagation();\n void onInstallSkill(\n (skill as SearchSkill).repo.githubOwner,\n (skill as SearchSkill).repo.githubRepoName,\n (skill as SearchSkill).slug,\n (skill as SearchSkill).description,\n (skill as SearchSkill).version ?? '',\n );\n }}\n >\n 安装\n </button>\n ) : null}\n </div>\n )}\n </article>\n );\n })}\n </div>\n {activeTab === 'plaza' && searchResults?.hasMore && (\n <div ref={loadMoreTriggerRef} className={styles.loadMore}>\n {loadingMore && <span className=\"text-sm text-[var(--text-muted)]\">加载中...</span>}\n </div>\n )}\n </>\n )}\n </div>\n </div>\n\n <div className={styles.footer}>\n <span className=\"text-xs\" style={{ color: 'var(--text-primary)', lineHeight: '18px' }}>\n 已选:{draftSelected.length}\n </span>\n <div className=\"flex gap-3\">\n <Button onClick={onClose} variant=\"default\">\n 取消\n </Button>\n <Button onClick={handleConfirm} color=\"major\">\n 确认\n </Button>\n </div>\n </div>\n </div>\n\n <UploadSkillModal\n open={uploadModalOpen}\n onClose={() => setUploadModalOpen(false)}\n onSuccess={handleUploadSuccess}\n />\n </div>\n );\n}","import { useCallback, useState } from 'react';\nimport type { AgentData } from '@/hooks/useAgentData';\nimport { MaskIcon } from '@/components/shared/MaskIcon';\nimport { SkillSelectorDrawer } from './SkillSelectorDrawer';\nimport type { SkillBasicInfo } from './skill-basic-info-cache';\nexport type { SkillBasicInfo } from './skill-basic-info-cache';\nimport { NameInitialIcon } from '@/components/NameInitialIcon';\nimport styles from './FormSkillsSection.module.css';\n\ninterface FormSkillsSectionProps {\n editingAgent?: AgentData | null;\n skills: string[];\n skillBasicInfos?: Map<string, SkillBasicInfo>;\n onSkillsChange: (skills: string[], skillBasicInfos?: Map<string, SkillBasicInfo>) => void;\n}\n\nexport function FormSkillsSection({ editingAgent, skills, skillBasicInfos, onSkillsChange }: FormSkillsSectionProps) {\n const [drawerOpen, setDrawerOpen] = useState(false);\n const readOnly = editingAgent?.source === 'seed';\n\n const handleRemoveSkill = useCallback(\n (skillToRemove: string) => {\n const newSkills = skills.filter((s) => s !== skillToRemove);\n const newDetails = new Map(skillBasicInfos);\n newDetails.delete(skillToRemove);\n onSkillsChange(newSkills, newDetails);\n },\n [skills, skillBasicInfos, onSkillsChange],\n );\n\n const handleConfirm = useCallback(\n (selectedSkills: string[], selectedSkillBasicInfos?: Map<string, SkillBasicInfo>) => {\n onSkillsChange(selectedSkills, selectedSkillBasicInfos);\n setDrawerOpen(false);\n },\n [onSkillsChange],\n );\n\n return (\n <div className=\"pt-6\">\n <div className=\"flex items-center justify-between gap-4 pb-4\">\n <h2 className=\"text-[16px] font-semibold text-[var(--text-primary)]\">技能配置</h2>\n {!readOnly && (\n <button\n type=\"button\"\n onClick={() => setDrawerOpen(true)}\n className=\"inline-flex h-[18px] shrink-0 items-center gap-1 text-[12px] text-[var(--text-primary)] transition hover:underline hover:underline-offset-2\"\n >\n <MaskIcon name=\"add\" className=\"h-3.5 w-3.5\" />\n <span>添加技能</span>\n </button>\n )}\n </div>\n\n {skills.length > 0 ? (\n <div className={styles.skillGrid}>\n {skills.map((skill) => (\n <div key={skill} className={styles.skillCard}>\n <NameInitialIcon name={skill} className={styles.cardIcon} />\n <div className={styles.cardContent}>\n <span className={styles.cardName}>{skill}</span>\n {skillBasicInfos?.get(skill)?.description && (\n <span className={styles.cardDescription}>{skillBasicInfos.get(skill)?.description}</span>\n )}\n </div>\n {!readOnly && (\n <button\n type=\"button\"\n onClick={() => handleRemoveSkill(skill)}\n className={styles.deleteButton}\n aria-label={`删除技能 ${skill}`}\n >\n <MaskIcon name=\"delete\" className=\"h-4 w-4\" />\n </button>\n )}\n </div>\n ))}\n </div>\n ) : (\n <div className={styles.emptyState}>暂未配置技能</div>\n )}\n\n <SkillSelectorDrawer\n open={drawerOpen}\n selectedSkills={skills}\n skillBasicInfos={skillBasicInfos}\n onConfirm={handleConfirm}\n onClose={() => setDrawerOpen(false)}\n />\n </div>\n );\n}","/*\n * *\n * * Copyright (C) Huawei Technologies Co., Ltd. 2026. All rights reserved.\n *\n */\n\n'use client';\n\nimport { useEffect, useMemo, useState } from 'react';\nimport { MaskIcon } from '@/components/shared/MaskIcon';\nimport { MarkdownContent } from './MarkdownContent';\nimport { NoSearchResultsState } from './shared/NoSearchResultsState';\nimport { Button } from './shared/Button';\nimport { SearchInput } from './shared/SearchInput';\n\nexport interface PromptSelectionItem {\n id: string;\n title: string;\n description: string;\n content: string;\n}\n\ninterface PromptSelectionModalProps {\n open: boolean;\n items: PromptSelectionItem[];\n initialSelectedId?: string | null;\n title?: string;\n searchPlaceholder?: string;\n cancelLabel?: string;\n confirmLabel?: string;\n onClose: () => void;\n onConfirm: (item: PromptSelectionItem) => void;\n}\n\nconst MODAL_WIDTH = 900;\nconst MODAL_VIEWPORT_OFFSET = 150;\nconst CARD_DETAIL_GAP = 16;\nconst LIST_SCROLLBAR_SLOT = 8;\nconst CONTENT_GAP = CARD_DETAIL_GAP - LIST_SCROLLBAR_SLOT;\nconst LIST_WIDTH = 240;\nconst LIST_SCROLL_CONTAINER_WIDTH = LIST_WIDTH + LIST_SCROLLBAR_SLOT;\nconst DETAIL_WIDTH = 596;\n\nfunction RefreshIcon() {\n return <MaskIcon name=\"refresh\" className=\"h-[18px] w-[18px]\" />;\n}\n\nfunction CloseIcon() {\n return (\n <svg className=\"h-[18px] w-[18px]\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M6 6L18 18\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" />\n <path d=\"M18 6L6 18\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n\nfunction normalizeSearch(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction PromptDetailContent({ item }: { item: PromptSelectionItem }) {\n return (\n <div className=\"h-full overflow-y-auto\">\n <MarkdownContent\n content={item.content}\n className=\"text-[12px] leading-7 text-[var(--modal-text)] [&_h1]:mb-3 [&_h1]:text-[16px] [&_h1]:font-semibold [&_h2]:mb-3 [&_h2]:text-[16px] [&_h2]:font-semibold [&_h3]:mb-2 [&_h3]:text-[16px] [&_h3]:font-semibold [&_ul]:mb-3 [&_li]:text-[var(--modal-text)] [&_p]:text-[var(--modal-text)]\"\n disableCommandPrefix\n />\n </div>\n );\n}\n\nfunction buildItemSummary(item: PromptSelectionItem): string {\n const summary = item.description.trim();\n if (summary) return summary;\n\n return item.content\n .replace(/^#{1,6}\\s+/gm, '')\n .replace(/[*_`>#-]/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction buildSearchFields(item: PromptSelectionItem): string[] {\n return [item.id, item.title, item.description, item.content];\n}\n\nfunction promptItemMatchesQuery(item: PromptSelectionItem, query: string): boolean {\n const lowered = query.toLowerCase();\n return buildSearchFields(item).some((field) => field.toLowerCase().includes(lowered));\n}\n\nexport function PromptSelectionModal({\n open,\n items,\n initialSelectedId = null,\n title = '灵魂模板',\n searchPlaceholder = '输入关键字搜索',\n cancelLabel = '取消',\n confirmLabel = '插入',\n onClose,\n onConfirm,\n}: PromptSelectionModalProps) {\n const [query, setQuery] = useState('');\n const [selectedId, setSelectedId] = useState<string | null>(initialSelectedId);\n\n useEffect(() => {\n if (!open) return;\n setQuery('');\n setSelectedId(initialSelectedId ?? items[0]?.id ?? null);\n }, [initialSelectedId, items, open]);\n\n useEffect(() => {\n if (!open) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose();\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [onClose, open]);\n\n const filteredItems = useMemo(() => {\n const normalized = normalizeSearch(query);\n if (!normalized) return items;\n\n return items.filter((item) => promptItemMatchesQuery(item, normalized));\n }, [items, query]);\n const hasNoMatches = filteredItems.length === 0;\n\n const selectedItem = useMemo(() => {\n if (hasNoMatches) return null;\n return filteredItems.find((item) => item.id === selectedId) ?? filteredItems[0];\n }, [filteredItems, hasNoMatches, selectedId]);\n\n useEffect(() => {\n if (!open) return;\n if (!selectedItem) {\n setSelectedId(null);\n return;\n }\n if (selectedItem.id !== selectedId) {\n setSelectedId(selectedItem.id);\n }\n }, [open, selectedId, selectedItem]);\n\n if (!open) return null;\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-start justify-center bg-[var(--overlay-backdrop-strong)] px-6 pb-[50px] pt-[100px]\"\n data-testid=\"prompt-selection-modal\"\n >\n <div\n className=\"flex w-full max-w-[900px] flex-col overflow-y-auto rounded-[8px] border border-[var(--modal-border)] bg-[var(--modal-surface)] p-6 shadow-[var(--modal-shadow)]\"\n style={{ width: MODAL_WIDTH, maxHeight: `calc(100vh - ${MODAL_VIEWPORT_OFFSET}px)` }}\n >\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-[18px] font-semibold leading-none text-[var(--modal-title-text)]\">{title}</h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md p-1 text-[var(--text-label-secondary)] transition-colors hover:text-[var(--text-primary)]\"\n aria-label=\"关闭提示词选择\"\n >\n <CloseIcon />\n </button>\n </div>\n\n <div className=\"mt-4 flex min-h-0 flex-col\">\n <div className=\"flex items-center gap-3\">\n <SearchInput\n wrapperClassName=\"min-w-0 flex-1\"\n value={query}\n onChange={(value) => setQuery(value)}\n placeholder={searchPlaceholder}\n aria-label={searchPlaceholder}\n data-testid=\"prompt-search-input\"\n />\n <button\n type=\"button\"\n onClick={() => setQuery('')}\n className=\"flex h-8 w-8 items-center justify-center rounded-[6px] border border-[var(--modal-muted-border)] bg-[var(--modal-surface)] transition hover:bg-[var(--modal-muted-surface-hover)]\"\n aria-label=\"清空搜索\"\n >\n <RefreshIcon />\n </button>\n </div>\n\n <div className=\"mt-4 flex min-h-0\" style={{ gap: CONTENT_GAP }}>\n {hasNoMatches ? (\n <section\n data-testid=\"prompt-empty-state\"\n className=\"flex min-h-[420px] flex-1 items-center justify-center rounded-[10px] border border-[var(--modal-muted-border)] bg-[var(--modal-surface)] px-8 py-10\"\n >\n <NoSearchResultsState\n onClear={() => setQuery('')}\n title=\"暂未匹配到数据\"\n description=\"没有匹配到符合条件的数据\"\n clearLabel=\"清除筛选器\"\n />\n </section>\n ) : (\n <>\n <aside\n className=\"flex shrink-0 flex-col gap-2 overflow-x-hidden overflow-y-auto bg-[var(--modal-surface)] pr-2\"\n style={{ width: LIST_SCROLL_CONTAINER_WIDTH }}\n >\n {filteredItems.map((item) => {\n const isSelected = item.id === selectedItem?.id;\n return (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => setSelectedId(item.id)}\n className={`block h-[68px] min-h-[68px] shrink-0 overflow-hidden rounded-[8px] p-3 text-left transition ${\n isSelected\n ? 'border border-[var(--modal-selected-border)] bg-[var(--modal-surface)] shadow-[var(--modal-selected-shadow)]'\n : 'border border-[var(--modal-muted-border)] bg-[var(--modal-muted-surface)] hover:bg-[var(--modal-surface)]'\n }`}\n data-testid={`prompt-list-item-${item.id}`}\n >\n <div className=\"flex h-full min-w-0 w-full flex-col justify-center overflow-hidden\">\n <div className=\"h-[22px] w-full truncate text-[14px] font-semibold leading-[22px] text-[var(--modal-text)]\">\n {item.title}\n </div>\n <div className=\"mt-1 h-[18px] w-full truncate overflow-hidden text-[12px] leading-[18px] text-[var(--modal-text-muted)]\">\n {buildItemSummary(item)}\n </div>\n </div>\n </button>\n );\n })}\n </aside>\n\n <section\n data-testid=\"prompt-detail-panel\"\n className=\"flex min-h-0 flex-1 flex-col overflow-hidden rounded-[10px] border border-[var(--modal-muted-border)] bg-[var(--modal-surface)] p-4\"\n style={{ width: DETAIL_WIDTH }}\n >\n {selectedItem ? (\n <PromptDetailContent item={selectedItem} />\n ) : (\n <div className=\"flex h-full items-center justify-center text-[13px] text-[var(--modal-empty-text)]\">请选择左侧提示词</div>\n )}\n </section>\n </>\n )}\n </div>\n\n <div className=\"mt-3 flex justify-end gap-3\">\n <Button\n onClick={onClose}\n color=\"default\"\n >\n {cancelLabel}\n </Button>\n <Button\n onClick={() => selectedItem && onConfirm(selectedItem)}\n color=\"major\"\n disabled={!selectedItem}\n data-testid=\"prompt-confirm-button\"\n >\n {confirmLabel}\n </Button>\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport type { AgentData } from '@/hooks/useAgentData';\nimport { MaskIcon } from '@/components/shared/MaskIcon';\nimport { PromptSelectionModal, type PromptSelectionItem } from '@/components/PromptSelectionModal';\nimport { MarkdownEditorWrapper } from './MarkdownEditorWrapper';\nimport { SoulConfig } from './SoulConfig';\nimport { INSPIRATION_TEMPLATES, buildTemplateMarkdown } from '../constants';\n\nconst PROMPT_SELECTION_ITEMS: PromptSelectionItem[] = INSPIRATION_TEMPLATES.map((template) => ({\n id: template.id,\n title: template.title,\n description: template.description,\n content: buildTemplateMarkdown(template),\n}));\n\ninterface FormSoulSectionProps {\n activeWorkingDraft: string;\n editingAgent?: AgentData | null;\n onDraftChange: (value: string) => void;\n}\n\nexport function FormSoulSection({ activeWorkingDraft, editingAgent, onDraftChange }: FormSoulSectionProps) {\n const [templateModalOpen, setTemplateModalOpen] = useState(false);\n\n const initialSelectedId = useMemo(() => PROMPT_SELECTION_ITEMS[0]?.id ?? null, []);\n const readOnly = editingAgent?.source === 'seed';\n\n const handleApplyTemplate = useCallback(\n (templateId: string) => {\n const template = INSPIRATION_TEMPLATES.find((item) => item.id === templateId);\n if (!template) return;\n\n const markdown = buildTemplateMarkdown(template);\n const existing = activeWorkingDraft.trim();\n onDraftChange(existing ? `${existing}\\n\\n${markdown}` : markdown);\n setTemplateModalOpen(false);\n },\n [activeWorkingDraft, onDraftChange],\n );\n\n return (\n <div className=\"pt-6\">\n <div className=\"flex items-center justify-between gap-4 pb-4\">\n <h2 className=\"text-[16px] font-semibold text-[var(--text-primary)]\">灵魂配置</h2>\n {!readOnly ? (\n <button\n type=\"button\"\n onClick={() => setTemplateModalOpen(true)}\n className=\"inline-flex h-[18px] shrink-0 items-center gap-1 text-[12px] text-[var(--text-primary)] transition hover:underline hover:underline-offset-2\"\n data-testid=\"soul-template-trigger\"\n >\n <MaskIcon name=\"template\" className=\"h-3.5 w-3.5\" />\n <span>模板</span>\n </button>\n ) : null}\n </div>\n\n {readOnly ? (\n <SoulConfig personality={editingAgent?.personality} agentId={editingAgent?.id ?? null} readOnly />\n ) : (\n <>\n <div className=\"h-[480px] rounded-lg border border-[var(--border-default)]\">\n <MarkdownEditorWrapper activeWorkingDraft={activeWorkingDraft} onDraftChange={onDraftChange} />\n </div>\n\n <PromptSelectionModal\n open={templateModalOpen}\n items={PROMPT_SELECTION_ITEMS}\n title=\"灵魂模板\"\n searchPlaceholder=\"输入关键字搜索\"\n cancelLabel=\"取消\"\n confirmLabel=\"插入\"\n initialSelectedId={initialSelectedId}\n onClose={() => setTemplateModalOpen(false)}\n onConfirm={(item) => handleApplyTemplate(item.id)}\n />\n </>\n )}\n </div>\n );\n}\n","import { FORM_STEPS } from '../constants';\nimport type { FormStepId } from '../constants';\nimport { MaskIcon } from '@/components/shared/MaskIcon';\n\ninterface FormStepNavProps {\n activeStep: FormStepId;\n onStepClick: (stepId: FormStepId) => void;\n}\n\nexport function FormStepNav({ activeStep, onStepClick }: FormStepNavProps) {\n return (\n <nav className=\"flex flex-col items-start gap-0 px-2\" aria-label=\"表单步骤\">\n {FORM_STEPS.map((step) => (\n <button\n key={step.id}\n type=\"button\"\n onClick={() => onStepClick(step.id)}\n className={`group flex w-full items-start text-left text-[12px] font-medium transition-colors ${\n activeStep === step.id ? 'text-[var(--text-primary)]' : 'text-[var(--text-tertiary)]'\n }`}\n >\n <span className=\"flex w-5 shrink-0 flex-col items-center\">\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-transparent\">\n <MaskIcon\n src={\n activeStep === step.id\n ? '/images/agent-management-icons/anchor-current.svg'\n : '/images/agent-management-icons/anchor-other.svg'\n }\n className=\"mt-[7px] h-2 w-2\"\n />\n </span>\n {step.id !== FORM_STEPS[FORM_STEPS.length - 1].id ? (\n <span className=\"mt-1 h-5 w-px bg-[var(--border-default)]\" aria-hidden=\"true\" />\n ) : null}\n </span>\n <span className=\"ml-3 pt-[1px] leading-5\">{step.label}</span>\n </button>\n ))}\n </nav>\n );\n}\n","import { useCallback, useEffect, useRef } from 'react';\nimport type { FormStepId } from '../constants';\n\nconst FORM_STEP_LOCK_MS = 800;\n\ninterface UseFormStepScrollOptions {\n scrollContainerRef: React.RefObject<HTMLDivElement | null>;\n stepRefs: Record<FormStepId, React.RefObject<HTMLElement | null>>;\n isManualOperating: boolean;\n setIsManualOperating: (v: boolean) => void;\n}\n\nexport function useFormStepScroll({\n scrollContainerRef,\n stepRefs,\n isManualOperating,\n setIsManualOperating,\n}: UseFormStepScrollOptions) {\n const manualStepTimerRef = useRef<number | null>(null);\n\n const clearManualStepTimer = useCallback(() => {\n if (manualStepTimerRef.current !== null) {\n window.clearTimeout(manualStepTimerRef.current);\n manualStepTimerRef.current = null;\n }\n }, []);\n\n const syncActiveStepFromScroll = useCallback(() => {\n const container = scrollContainerRef.current;\n const soulNode = stepRefs.soul.current;\n if (!container || !soulNode) return;\n\n const containerRect = container.getBoundingClientRect();\n const soulRect = soulNode.getBoundingClientRect();\n const soulRelativeTop = soulRect.top - containerRect.top;\n\n // Active step is determined by scroll position\n // This is informational; actual activeStep state lives in FormContent\n }, [scrollContainerRef, stepRefs.soul]);\n\n const scrollToStep = useCallback(\n (stepId: FormStepId) => {\n const container = scrollContainerRef.current;\n const ref = stepRefs[stepId];\n if (!container || !ref.current) return;\n\n const containerRect = container.getBoundingClientRect();\n const targetRect = ref.current.getBoundingClientRect();\n const offsetTop = targetRect.top - containerRect.top + container.scrollTop;\n const nextTop = Math.max(0, offsetTop - 24);\n\n container.scrollTo({\n top: nextTop,\n behavior: 'smooth',\n });\n },\n [scrollContainerRef, stepRefs],\n );\n\n const scrollToBasicTop = useCallback(() => {\n const container = scrollContainerRef.current;\n if (!container) return;\n\n container.scrollTo({\n top: 0,\n behavior: 'smooth',\n });\n }, [scrollContainerRef]);\n\n const handleStepClick = useCallback(\n (stepId: FormStepId) => {\n clearManualStepTimer();\n setIsManualOperating(true);\n\n if (stepId === 'basic') {\n scrollToBasicTop();\n } else {\n scrollToStep(stepId);\n }\n\n manualStepTimerRef.current = window.setTimeout(() => {\n manualStepTimerRef.current = null;\n setIsManualOperating(false);\n }, FORM_STEP_LOCK_MS);\n },\n [clearManualStepTimer, setIsManualOperating, scrollToBasicTop, scrollToStep],\n );\n\n useEffect(() => {\n const container = scrollContainerRef.current;\n if (!container) return undefined;\n\n const handleScroll = () => {\n if (isManualOperating) return;\n syncActiveStepFromScroll();\n };\n\n container.addEventListener('scroll', handleScroll, { passive: true });\n return () => container.removeEventListener('scroll', handleScroll);\n }, [scrollContainerRef, isManualOperating, syncActiveStepFromScroll]);\n\n useEffect(\n () => () => {\n clearManualStepTimer();\n },\n [clearManualStepTimer],\n );\n\n return { handleStepClick };\n}","import { useCallback, useEffect, useLayoutEffect, useState, type RefObject } from 'react';\nimport { MODEL_MENU_MAX_HEIGHT, MODEL_MENU_OFFSET } from '../constants';\n\ninterface UseModelMenuParams {\n modelGroupCount: number;\n modelItemCount: number;\n modelMenuOpen: boolean;\n modelMenuRef: RefObject<HTMLDivElement>;\n modelTriggerRef: RefObject<HTMLButtonElement>;\n onClose: () => void;\n}\n\nexport function useModelMenu({\n modelGroupCount,\n modelItemCount,\n modelMenuOpen,\n modelMenuRef,\n modelTriggerRef,\n onClose,\n}: UseModelMenuParams) {\n const [openAbove, setOpenAbove] = useState(false);\n const [modelMenuPosition, setModelMenuPosition] = useState<{ top: number; left: number; width: number } | null>(null);\n\n const updateModelMenuPosition = useCallback(() => {\n if (!modelMenuOpen || !modelTriggerRef.current) return;\n const rect = modelTriggerRef.current.getBoundingClientRect();\n const estimatedMenuHeight =\n modelMenuRef.current?.offsetHeight ??\n Math.min(Math.max(modelItemCount, 1) * 36 + modelGroupCount * 22 + 54, MODEL_MENU_MAX_HEIGHT);\n const spaceBelow = window.innerHeight - rect.bottom;\n const nextOpenAbove = spaceBelow < estimatedMenuHeight + MODEL_MENU_OFFSET;\n setOpenAbove(nextOpenAbove);\n setModelMenuPosition({\n top: nextOpenAbove ? rect.top - MODEL_MENU_OFFSET : rect.bottom + MODEL_MENU_OFFSET,\n left: rect.left,\n width: rect.width,\n });\n }, [modelGroupCount, modelItemCount, modelMenuOpen, modelMenuRef, modelTriggerRef]);\n\n useEffect(() => {\n if (!modelMenuOpen) return;\n\n const handlePointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (modelMenuRef.current?.contains(target) || modelTriggerRef.current?.contains(target)) return;\n onClose();\n };\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n onClose();\n modelTriggerRef.current?.focus();\n };\n\n document.addEventListener('mousedown', handlePointerDown);\n document.addEventListener('keydown', handleEscape);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown);\n document.removeEventListener('keydown', handleEscape);\n };\n }, [modelMenuOpen, modelMenuRef, modelTriggerRef, onClose]);\n\n useLayoutEffect(() => {\n if (!modelMenuOpen) {\n setModelMenuPosition(null);\n setOpenAbove(false);\n return;\n }\n updateModelMenuPosition();\n }, [modelMenuOpen, updateModelMenuPosition]);\n\n useEffect(() => {\n if (!modelMenuOpen) return;\n const handleViewportChange = () => updateModelMenuPosition();\n window.addEventListener('resize', handleViewportChange);\n window.addEventListener('scroll', handleViewportChange, true);\n return () => {\n window.removeEventListener('resize', handleViewportChange);\n window.removeEventListener('scroll', handleViewportChange, true);\n };\n }, [modelMenuOpen, updateModelMenuPosition]);\n\n return {\n modelMenuPosition,\n openAbove,\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { apiFetch } from '@/utils/api-client';\nimport {\n CUSTOM_MODEL_GROUP_LABEL,\n HUAWEI_MAAS_GROUP_KEY,\n FREE_HUAWEI_MAAS_GROUP_LABEL,\n normalizeModel,\n protocolGroupKey,\n protocolGroupLabel,\n} from '../../models-panel/utils';\nimport {\n HUAWEI_PROVIDER_LABEL,\n RELAYCLAW_CLIENT,\n} from '../constants';\nimport type { CreateModelOption, MaaSModelResponseItem } from '../types';\n\nfunction normalizeInitialModelName(value: string | undefined | null): string {\n const trimmed = value?.trim() ?? '';\n if (!trimmed) return '';\n if (!trimmed.startsWith('model_config:')) return trimmed;\n const parts = trimmed.split(':');\n return parts.length >= 3 ? parts.slice(2).join(':').trim() : trimmed;\n}\n\nfunction pickStringField(item: Record<string, unknown>, candidates: string[]): string | undefined {\n for (const key of candidates) {\n const value = item[key];\n if (typeof value === 'string' && value.trim().length > 0) return value.trim();\n }\n return undefined;\n}\n\nfunction parseAccountRefFromModelItem(item: MaaSModelResponseItem): string | null {\n if (typeof item.accountRef === 'string' && item.accountRef.trim().length > 0) {\n return item.accountRef.trim();\n }\n if (item.provider === HUAWEI_PROVIDER_LABEL) return 'huawei-maas';\n const rawId = typeof item.id === 'string' ? item.id.trim() : '';\n if (!rawId) return null;\n if (!rawId.startsWith('model_config:')) return null;\n const rest = rawId.slice('model_config:'.length);\n const splitIndex = rest.indexOf(':');\n return splitIndex >= 0 ? rest.slice(0, splitIndex) : null;\n}\n\nfunction parseModelNameFromModelItemId(rawId: string, accountRef: string, fallbackName: string): string {\n if (!rawId.startsWith('model_config:')) return fallbackName;\n const prefix = `model_config:${accountRef}:`;\n if (!rawId.startsWith(prefix)) return fallbackName;\n return rawId.slice(prefix.length) || fallbackName;\n}\n\nfunction toModelOption(item: MaaSModelResponseItem, index: number): CreateModelOption | null {\n if (item.enabled === false) return null;\n const normalized = item as Record<string, unknown>;\n const card = normalizeModel(item, index);\n const modelLabel = card.name;\n const accountRef = parseAccountRefFromModelItem(item);\n if (!modelLabel || !accountRef) return null;\n\n const providerLabel = pickStringField(normalized, ['provider']) ?? card.developer;\n const rawId =\n typeof item.id === 'string' && item.id.trim().length > 0 ? item.id.trim() : `${accountRef}::${modelLabel}`;\n const model = parseModelNameFromModelItemId(rawId, accountRef, modelLabel);\n\n return {\n id: rawId,\n name: modelLabel,\n icon: pickStringField(normalized, ['icon', 'logo', 'image', 'avatar']),\n providerGroup: providerLabel,\n accountRef,\n client: RELAYCLAW_CLIENT,\n model,\n modelLabel,\n groupId: protocolGroupKey(card),\n groupLabel: protocolGroupLabel(card),\n };\n}\n\nfunction buildFallbackSelectedOption(accountRef: string | null, model: string | null): CreateModelOption | null {\n if (!model) return null;\n const effectiveAccountRef = accountRef ?? 'huawei-maas';\n const isHuawei = effectiveAccountRef === 'huawei-maas';\n const groupId = isHuawei ? HUAWEI_MAAS_GROUP_KEY : 'custom_models';\n return {\n id: `${effectiveAccountRef}::${model}`,\n name: model,\n accountRef: effectiveAccountRef,\n client: RELAYCLAW_CLIENT,\n model,\n modelLabel: model,\n groupId,\n groupLabel: isHuawei ? FREE_HUAWEI_MAAS_GROUP_LABEL : CUSTOM_MODEL_GROUP_LABEL,\n };\n}\n\ninterface UseModelSelectionOptions {\n editingDefaultModel?: string | null;\n editingAccountRef?: string | null;\n defaultToFirstModel?: boolean;\n}\n\ninterface UseModelSelectionResult {\n models: CreateModelOption[];\n modelGroups: Array<{ id: string; label: string; items: CreateModelOption[] }>;\n loading: boolean;\n selectedModel: CreateModelOption | null;\n selectedModelId: string | null;\n missingModel: boolean;\n onSelectModel: (modelId: string) => void;\n resolveForSave: () => { accountRef: string; model: string } | null;\n}\n\nexport function useModelSelection({\n editingDefaultModel,\n editingAccountRef,\n defaultToFirstModel = false,\n}: UseModelSelectionOptions = {}): UseModelSelectionResult {\n const [marketplaceModels, setMarketplaceModels] = useState<MaaSModelResponseItem[]>([]);\n const [loadingModels, setLoadingModels] = useState(false);\n const [selectedModelId, setSelectedModelId] = useState<string | null>(null);\n\n // Fetch models on mount\n useEffect(() => {\n let cancelled = false;\n setLoadingModels(true);\n void (async () => {\n try {\n const response = await apiFetch('/api/maas-models');\n if (!response.ok) throw new Error(`模型广场加载失败 (${response.status})`);\n const body = (await response.json()) as { list?: MaaSModelResponseItem[]; models?: MaaSModelResponseItem[] };\n const source = Array.isArray(body.list) ? body.list : Array.isArray(body.models) ? body.models : [];\n if (!cancelled) setMarketplaceModels(source);\n } catch {\n if (!cancelled) setMarketplaceModels([]);\n } finally {\n if (!cancelled) setLoadingModels(false);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, []);\n\n const normalizedEditingModel = normalizeInitialModelName(editingDefaultModel ?? null);\n const availableModels = useMemo(() => {\n const items = marketplaceModels.map((item, index) => toModelOption(item, index)).filter((item): item is CreateModelOption => item !== null);\n const deduped = new Map<string, CreateModelOption>();\n for (const item of items) deduped.set(item.id, item);\n return Array.from(deduped.values());\n }, [marketplaceModels]);\n\n const modelGroups = useMemo(() => {\n return availableModels.reduce<Array<{ id: string; label: string; items: CreateModelOption[] }>>((acc, item) => {\n const existing = acc.find((group) => group.id === item.groupId);\n if (existing) {\n existing.items.push(item);\n return acc;\n }\n acc.push({ id: item.groupId, label: item.groupLabel, items: [item] });\n return acc;\n }, []);\n }, [availableModels]);\n\n const selectionHint = useMemo(\n () => ({\n model: normalizedEditingModel || null,\n accountRef: editingAccountRef ?? null,\n }),\n [normalizedEditingModel, editingAccountRef],\n );\n\n const selectedModel = useMemo(() => {\n if (selectedModelId === '') return null;\n if (selectedModelId) {\n const matchedById = availableModels.find((m) => m.id === selectedModelId);\n if (matchedById) return matchedById;\n }\n if (selectionHint.accountRef && selectionHint.model) {\n const matchedByPair = availableModels.find(\n (m) => m.accountRef === selectionHint.accountRef && m.model === selectionHint.model,\n );\n if (matchedByPair) return matchedByPair;\n }\n if (selectionHint.model) {\n const matchedByModel = availableModels.find((m) => m.model === selectionHint.model);\n if (matchedByModel) return matchedByModel;\n }\n if (defaultToFirstModel && availableModels.length > 0) {\n return availableModels[0];\n }\n return buildFallbackSelectedOption(selectionHint.accountRef, selectionHint.model);\n }, [availableModels, selectedModelId, selectionHint, defaultToFirstModel]);\n\n const missingModel = useMemo(() => {\n if (!selectionHint.model) return false;\n return !availableModels.some(\n (item) => item.model === selectionHint.model && item.accountRef === selectionHint.accountRef,\n );\n }, [availableModels, selectionHint]);\n\n useEffect(() => {\n if (!selectedModel) return;\n if (selectedModelId === selectedModel.id) return;\n setSelectedModelId(selectedModel.id);\n }, [selectedModel, selectedModelId]);\n\n const onSelectModel = useCallback(\n (modelId: string) => {\n setSelectedModelId(modelId);\n },\n [],\n );\n\n const resolveForSave = useCallback(() => {\n if (!selectedModel) return null;\n return {\n accountRef: selectedModel.accountRef,\n model: selectedModel.model,\n };\n }, [selectedModel]);\n\n return {\n models: availableModels,\n modelGroups,\n loading: loadingModels,\n selectedModel,\n selectedModelId,\n missingModel,\n onSelectModel,\n resolveForSave,\n };\n}\n\nexport { normalizeInitialModelName };\n","import { useCallback, useState } from 'react';\nimport { uploadAvatarAsset } from '@/components/hub-agent-editor.client';\n\ninterface UseAvatarUploadOptions {\n onSuccess?: (url: string) => void;\n maxSizeBytes?: number;\n}\n\ninterface UseAvatarUploadResult {\n uploading: boolean;\n error: string | null;\n handleUpload: (event: React.ChangeEvent<HTMLInputElement>) => Promise<void>;\n}\n\nconst DEFAULT_MAX_SIZE = 200 * 1024; // 200KB\n\nexport function useAvatarUpload({\n onSuccess,\n maxSizeBytes = DEFAULT_MAX_SIZE,\n}: UseAvatarUploadOptions = {}): UseAvatarUploadResult {\n const [uploading, setUploading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const handleUpload = useCallback(\n async (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n if (!file) return;\n\n if (file.size > maxSizeBytes) {\n setError('图片大小不能超过 200KB');\n return;\n }\n\n setUploading(true);\n setError(null);\n\n try {\n const url = await uploadAvatarAsset(file);\n onSuccess?.(url);\n } catch (err) {\n setError(err instanceof Error ? err.message : '上传失败');\n } finally {\n setUploading(false);\n }\n },\n [maxSizeBytes, onSuccess],\n );\n\n return { uploading, error, handleUpload };\n}\n","import { useCallback, useMemo, useRef, useState } from 'react';\nimport type { AgentData } from '@/hooks/useAgentData';\nimport type { FormStepId } from '../constants';\nimport {\n buildGeneratedAvatarDataUrl,\n getRandomPresetAvatar,\n resolveInitialAvatar,\n isDuplicateNameErrorMessage,\n} from '../utils';\nimport { AGENT_NAME_VALIDATION_MESSAGE, DEFAULT_PRESET_AVATAR } from '../constants';\nimport { apiFetch } from '@/utils/api-client';\nimport { normalizeAgentSaveErrorMessage } from '@/utils/agent-save-error';\nimport { buildAgentPayload } from '../../hub-agent-editor.payload';\nimport type { HubAgentEditorFormState } from '../../hub-agent-editor.model';\nimport { BasicInfoSection } from './BasicInfoSection';\nimport { FormFooter } from './FormFooter';\nimport { FormHeader } from './FormHeader';\nimport { FormSkillsSection, type SkillBasicInfo } from './FormSkillsSection';\nimport { FormSoulSection } from './FormSoulSection';\nimport { FormStepNav } from './FormStepNav';\nimport { useFormStepScroll } from '../hooks/useFormStepScroll';\nimport { useModelMenu } from '../hooks/useModelMenu';\nimport { useModelSelection, normalizeInitialModelName } from '../hooks/useModelSelection';\nimport { useAvatarUpload } from '../hooks/useAvatarUpload';\n\ninterface FormContentProps {\n editingAgent?: AgentData | null;\n formMode: 'create' | 'edit';\n prefillData?: Partial<AgentData> | null;\n onCancel: () => void;\n onSaveSuccess: () => void;\n onBackToDetail: () => void;\n onBackToList: () => void;\n}\n\nfunction autoSlug(name: string): string {\n return name\n .trim()\n .toLowerCase()\n .replace(/[\\s_]+/g, '-')\n .replace(/[^a-z0-9\\u4e00-\\u9fff-]/g, '')\n .slice(0, 40);\n}\n\nfunction validateAgentName(name: string): string | null {\n if (!name) return AGENT_NAME_VALIDATION_MESSAGE;\n if (name !== name.trim()) return AGENT_NAME_VALIDATION_MESSAGE;\n if (name.length < 2 || name.length > 64) return AGENT_NAME_VALIDATION_MESSAGE;\n if (!/^[\\u4e00-\\u9fffA-Za-z0-9 _-]+$/.test(name)) return AGENT_NAME_VALIDATION_MESSAGE;\n return null;\n}\n\nfunction generateRandomAgentId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).slice(2, 8);\n return `agent-${timestamp}${random}`.slice(0, 64);\n}\n\nconst DEFAULT_ROLE_DESCRIPTION = '通用智能体助手';\n\nexport function FormContent({ editingAgent, formMode, prefillData, onCancel, onSaveSuccess, onBackToDetail, onBackToList }: FormContentProps) {\n const [draftName, setDraftName] = useState(editingAgent?.displayName ?? prefillData?.displayName ?? 'BOT');\n const [draftDescription, setDraftDescription] = useState(editingAgent?.roleDescription ?? prefillData?.roleDescription ?? '');\n const [draftAvatar, setDraftAvatar] = useState<string>(\n editingAgent ? resolveInitialAvatar(editingAgent) : prefillData?.avatar ?? DEFAULT_PRESET_AVATAR,\n );\n const [draftDefaultModel, setDraftDefaultModel] = useState(normalizeInitialModelName(editingAgent?.defaultModel ?? prefillData?.defaultModel));\n const [draftImageModel, setDraftImageModel] = useState(normalizeInitialModelName(editingAgent?.imageModel ?? prefillData?.imageModel));\n const [activeWorkingDraft, setActiveWorkingDraft] = useState(editingAgent?.personality ?? prefillData?.personality ?? '');\n const [isManualOperating, setIsManualOperating] = useState(false);\n const [saving, setSaving] = useState(false);\n const [globalError, setGlobalError] = useState<string | null>(null);\n const [nameSubmitError, setNameSubmitError] = useState<string | null>(null);\n const [modelError, setModelError] = useState<string | null>(null);\n\n const [draftSkills, setDraftSkills] = useState<string[]>(editingAgent?.skills ?? prefillData?.skills ?? []);\n const [draftSkillBasicInfos, setDraftSkillBasicInfos] = useState<Map<string, SkillBasicInfo>>(new Map());\n const [modelMenuOpen, setModelMenuOpen] = useState(false);\n const [imageModelMenuOpen, setImageModelMenuOpen] = useState(false);\n const [agentId] = useState(() => editingAgent?.id ?? generateRandomAgentId());\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n const modelTriggerRef = useRef<HTMLButtonElement>(null);\n const modelMenuRef = useRef<HTMLDivElement>(null);\n const imageModelTriggerRef = useRef<HTMLButtonElement>(null);\n const imageModelMenuRef = useRef<HTMLDivElement>(null);\n const scrollContainerRef = useRef<HTMLDivElement | null>(null);\n const basicRef = useRef<HTMLDivElement>(null);\n const soulRef = useRef<HTMLDivElement | null>(null);\n const skillsRef = useRef<HTMLDivElement | null>(null);\n\n const nameError = useMemo(() => validateAgentName(draftName), [draftName]);\n const inlineNameError = nameError ?? nameSubmitError;\n const isConfirmDisabled = Boolean(inlineNameError) || saving;\n const displayAvatar = draftAvatar ? draftAvatar : buildGeneratedAvatarDataUrl(draftName || '智');\n\n const stepRefs: Record<FormStepId, React.RefObject<HTMLElement | null>> = {\n basic: basicRef,\n soul: soulRef,\n skills: skillsRef,\n };\n\n const { handleStepClick } = useFormStepScroll({\n scrollContainerRef,\n stepRefs,\n isManualOperating,\n setIsManualOperating,\n });\n\n const editingAccountRef = editingAgent?.accountRef ?? editingAgent?.providerProfileId ?? null;\n const editingImageAccountRef = editingAgent?.imageAccountRef ?? null;\n const {\n models: marketplaceModels,\n loading: loadingModels,\n modelGroups,\n selectedModel,\n missingModel,\n onSelectModel: onModelSelect,\n resolveForSave,\n } =\n useModelSelection({\n editingDefaultModel: editingAgent?.defaultModel,\n editingAccountRef,\n defaultToFirstModel: formMode === 'create',\n });\n\n const {\n models: imageModels,\n loading: loadingImageModels,\n modelGroups: rawImageModelGroups,\n selectedModel: selectedImageModel,\n missingModel: missingImageModel,\n onSelectModel: onImageModelSelect,\n resolveForSave: resolveImageModelForSave,\n } =\n useModelSelection({\n editingDefaultModel: editingAgent?.imageModel,\n editingAccountRef: editingImageAccountRef,\n defaultToFirstModel: false,\n });\n\n const imageModelGroups = useMemo(() => {\n return rawImageModelGroups\n .map((group) => ({\n ...group,\n items: group.items.filter((item) => item.model.toLowerCase().includes('-vl-')),\n }))\n .filter((group) => group.items.length > 0);\n }, [rawImageModelGroups]);\n\n const { modelMenuPosition, openAbove } = useModelMenu({\n modelGroupCount: modelGroups.length,\n modelItemCount: modelGroups.reduce((total, group) => total + group.items.length, 0),\n modelMenuOpen,\n modelMenuRef,\n modelTriggerRef,\n onClose: () => setModelMenuOpen(false),\n });\n\n const { modelMenuPosition: imageModelMenuPosition, openAbove: imageModelOpenAbove } = useModelMenu({\n modelGroupCount: imageModelGroups.length,\n modelItemCount: imageModelGroups.reduce((total, group) => total + group.items.length, 0),\n modelMenuOpen: imageModelMenuOpen,\n modelMenuRef: imageModelMenuRef,\n modelTriggerRef: imageModelTriggerRef,\n onClose: () => setImageModelMenuOpen(false),\n });\n\n const { uploading: uploadingAvatar, error: avatarError, handleUpload: handleAvatarUpload } = useAvatarUpload({\n onSuccess: (url) => setDraftAvatar(url),\n });\n\n const onSelectModel = useCallback(\n (modelId: string) => {\n onModelSelect(modelId);\n const selected = marketplaceModels.find((item) => item.id === modelId);\n setDraftDefaultModel(selected?.model ?? normalizeInitialModelName(modelId));\n setModelError(null);\n setModelMenuOpen(false);\n },\n [onModelSelect, marketplaceModels],\n );\n\n const onSelectImageModel = useCallback(\n (modelId: string) => {\n onImageModelSelect(modelId);\n const selected = imageModels.find((item) => item.id === modelId);\n setDraftImageModel(selected?.model ?? normalizeInitialModelName(modelId));\n setImageModelMenuOpen(false);\n },\n [onImageModelSelect, imageModels],\n );\n\n const onClearImageModel = useCallback(() => {\n onImageModelSelect('');\n setDraftImageModel('');\n setImageModelMenuOpen(false);\n }, [onImageModelSelect]);\n\n const handleSave = useCallback(async () => {\n if (nameError) {\n return;\n }\n\n setSaving(true);\n setGlobalError(null);\n setModelError(null);\n\n try {\n const resolved = resolveForSave();\n const resolvedAccountRef = resolved?.accountRef ?? editingAccountRef ?? '';\n const resolvedModel = resolved?.model ?? selectedModel?.model ?? draftDefaultModel;\n if (!resolvedModel) {\n setModelError('请选择一个模型');\n return;\n }\n const safeName = draftName.trim();\n const safeDescription =\n draftDescription.trim() || (formMode === 'create' ? DEFAULT_ROLE_DESCRIPTION : editingAgent?.roleDescription ?? '');\n const mentionSeed = autoSlug(safeName) || agentId;\n\n const resolvedImageModel = resolveImageModelForSave();\n const resolvedImageAccountRef = resolvedImageModel?.accountRef ?? editingImageAccountRef ?? undefined;\n const resolvedImageModelName = resolvedImageModel?.model ?? selectedImageModel?.model ?? draftImageModel;\n\n const finalImageModel = resolvedImageModelName && resolvedImageModelName.trim() !== '' ? resolvedImageModelName.trim() : undefined;\n const finalImageAccountRef = finalImageModel ? (resolvedImageAccountRef ?? 'huawei-maas') : undefined;\n\n const formState: HubAgentEditorFormState = {\n agentId,\n name: safeName,\n displayName: safeName,\n nickname: '',\n avatar: draftAvatar,\n colorPrimary: '#9B7EBD',\n colorSecondary: '#E8DFF5',\n mentionPatterns: `@${mentionSeed}`,\n roleDescription: safeDescription,\n personality: activeWorkingDraft,\n teamStrengths: '',\n caution: '',\n strengths: '',\n client: selectedModel?.client ?? 'relayclaw',\n accountRef: resolvedAccountRef,\n defaultModel: resolvedModel,\n imageModel: finalImageModel,\n imageAccountRef: finalImageAccountRef,\n commandArgs: '',\n cliConfigArgs: [],\n ocProviderName: '',\n embeddedAcpExecutablePath: '',\n embeddedAcpArgs: '',\n embeddedAcpCwd: '',\n embeddedAcpEnvText: '',\n sessionChain: 'true',\n maxPromptTokens: '',\n maxContextTokens: '',\n maxMessages: '',\n maxContentLengthPerMsg: '',\n ...(prefillData?.creationSource ? { creationSource: prefillData.creationSource } : {}),\n };\n const payload = buildAgentPayload(formState, editingAgent ?? null);\n payload.skills = draftSkills;\n\n const method = formMode === 'edit' && editingAgent ? 'PATCH' : 'POST';\n const url = formMode === 'edit' && editingAgent ? `/api/agents/${editingAgent.id}` : '/api/agents';\n\n const res = await apiFetch(url, {\n method,\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n\n if (!res.ok) {\n const error = (await res.json().catch(() => ({}))) as { error?: string };\n const nextError = normalizeAgentSaveErrorMessage(error.error) ?? (formMode === 'edit' ? '保存失败' : '创建失败');\n if (nextError === '模型不存在,请重新选择') {\n setModelError(nextError);\n return;\n }\n if (isDuplicateNameErrorMessage(nextError)) {\n setNameSubmitError(nextError);\n return;\n }\n throw new Error(nextError);\n }\n\n onSaveSuccess();\n } catch (err) {\n const nextError =\n normalizeAgentSaveErrorMessage(err instanceof Error ? err.message : null) ?? (formMode === 'edit' ? '保存失败' : '创建失败');\n if (nextError === '模型不存在,请重新选择') setModelError(nextError);\n else if (isDuplicateNameErrorMessage(nextError)) setNameSubmitError(nextError);\n else setGlobalError(nextError);\n } finally {\n setSaving(false);\n }\n }, [\n draftName,\n draftDescription,\n draftDefaultModel,\n draftImageModel,\n draftAvatar,\n draftSkills,\n activeWorkingDraft,\n formMode,\n editingAgent,\n editingAccountRef,\n editingImageAccountRef,\n nameError,\n agentId,\n prefillData,\n resolveForSave,\n resolveImageModelForSave,\n selectedModel,\n selectedImageModel,\n onSaveSuccess,\n ]);\n\n const displayName = editingAgent?.displayName ?? prefillData?.displayName ?? '';\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <div ref={scrollContainerRef} className=\"min-h-0 flex-1 overflow-y-auto\">\n <div className=\"mx-auto grid min-h-full w-full max-w-[1480px] grid-cols-[minmax(112px,132px)_minmax(0,1092px)_minmax(112px,132px)] gap-x-8 px-6 pb-6 lg:px-8\">\n <div className=\"sticky top-0 z-10 row-span-2 min-w-0 self-start justify-self-stretch\">\n <div className=\"flex justify-end\">\n <FormStepNav activeStep=\"basic\" onStepClick={handleStepClick} />\n </div>\n </div>\n\n <div className=\"sticky top-0 z-10 col-start-2 row-start-1 min-w-0 bg-[var(--surface-panel)] pb-4\">\n <FormHeader\n displayName={displayName}\n formMode={formMode}\n onBackToDetail={onBackToDetail}\n onBackToList={onBackToList}\n />\n </div>\n\n <div className=\"col-start-2 row-start-2 min-w-0 mt-4\">\n <div ref={basicRef} className=\"flex flex-col gap-12\">\n <BasicInfoSection\n avatarError={avatarError}\n displayAvatar={displayAvatar}\n draftDefaultModel={draftDefaultModel}\n draftImageModel={draftImageModel ?? ''}\n draftDescription={draftDescription}\n draftName={draftName}\n fileInputRef={fileInputRef}\n inlineNameError={inlineNameError}\n loadingModels={loadingModels}\n modelGroups={modelGroups}\n modelMenuOpen={modelMenuOpen}\n modelMenuPosition={modelMenuPosition}\n modelMenuRef={modelMenuRef}\n modelTriggerRef={modelTriggerRef}\n modelError={modelError ?? (missingModel ? '模型不存在,请重新选择' : null)}\n loadingImageModels={loadingImageModels}\n imageModelGroups={imageModelGroups}\n imageModelMenuOpen={imageModelMenuOpen}\n imageModelMenuPosition={imageModelMenuPosition}\n imageModelMenuRef={imageModelMenuRef}\n imageModelTriggerRef={imageModelTriggerRef}\n missingImageModel={missingImageModel}\n onAvatarUpload={handleAvatarUpload}\n onDescriptionChange={setDraftDescription}\n onNameChange={(value) => {\n setDraftName(value);\n setNameSubmitError(null);\n }}\n onRandomAvatar={() => setDraftAvatar(getRandomPresetAvatar())}\n onSelectModel={onSelectModel}\n onToggleModelMenu={() => setModelMenuOpen((prev) => !prev)}\n onSelectImageModel={onSelectImageModel}\n onClearImageModel={onClearImageModel}\n onToggleImageModelMenu={() => setImageModelMenuOpen((prev) => !prev)}\n selectedModel={selectedModel}\n selectedImageModel={selectedImageModel}\n openAbove={openAbove}\n imageModelOpenAbove={imageModelOpenAbove}\n uploadingAvatar={uploadingAvatar}\n />\n\n <div ref={soulRef}>\n <FormSoulSection\n activeWorkingDraft={activeWorkingDraft}\n editingAgent={editingAgent}\n onDraftChange={setActiveWorkingDraft}\n />\n </div>\n\n <div ref={skillsRef}>\n <FormSkillsSection\n editingAgent={editingAgent}\n skills={draftSkills}\n skillBasicInfos={draftSkillBasicInfos}\n onSkillsChange={(skills, skillBasicInfos) => {\n setDraftSkills(skills);\n if (skillBasicInfos) setDraftSkillBasicInfos(skillBasicInfos);\n }}\n />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <FormFooter\n error={globalError}\n formMode={formMode}\n isConfirmDisabled={isConfirmDisabled}\n onCancel={onCancel}\n onSave={handleSave}\n saving={saving}\n />\n </div>\n );\n}\n","import type { AgentData } from '@/hooks/useAgentData';\nimport { MaskIcon } from '@/components/shared/MaskIcon';\nimport type { FormMode, PanelView } from './types';\nimport { ListGrid } from './components/ListGrid';\nimport { Toolbar } from './components/Toolbar';\nimport { DetailContent } from './components/DetailContent';\nimport { DetailSkillsSection } from './components/DetailSkillsSection';\nimport { SoulConfig } from './components/SoulConfig';\nimport { FormContent } from './components/FormContent';\nimport { Button } from '@/components/shared/Button';\n\nexport interface AgentManagementViewProps {\n // State\n agents: AgentData[];\n filteredAgents: AgentData[];\n searchQuery: string;\n sourceFilter: import('./utils').AgentSourceFilter;\n selectedAgent: AgentData | null;\n currentView: PanelView;\n formMode: FormMode;\n editingAgent: AgentData | null;\n previousView: PanelView | null;\n prefillData: Partial<AgentData> | null;\n loading?: boolean;\n\n // Actions\n onSearchChange: (query: string) => void;\n onClearSearch: () => void;\n onSourceFilterChange: (filter: import('./utils').AgentSourceFilter) => void;\n onRefresh: () => void;\n onSelectAgent: (agentId: string) => void;\n onOpenCreate: () => void;\n onOpenEdit: (agentId: string) => void;\n onDeleteAgent: (agentId: string) => void;\n onCancel: () => void;\n onSaveSuccess: () => void;\n onBackToDetail: () => void;\n onBackToList: () => void;\n}\n\nfunction ListView({\n agents,\n filteredAgents,\n searchQuery,\n sourceFilter,\n onSearchChange,\n onClearSearch,\n onSourceFilterChange,\n onRefresh,\n onSelectAgent,\n onOpenCreate,\n onOpenEdit,\n onDeleteAgent,\n loading,\n}: {\n agents: AgentData[];\n filteredAgents: AgentData[];\n searchQuery: string;\n sourceFilter: import('./utils').AgentSourceFilter;\n onSearchChange: (query: string) => void;\n onClearSearch: () => void;\n onSourceFilterChange: (filter: import('./utils').AgentSourceFilter) => void;\n onRefresh: () => void;\n onSelectAgent: (agentId: string) => void;\n onOpenCreate: () => void;\n onOpenEdit: (agentId: string) => void;\n onDeleteAgent: (agentId: string) => void;\n loading?: boolean;\n}) {\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-6\">\n <div className=\"flex items-center justify-between shrink-0\">\n <h1 className=\"ui-page-title\">智能体管理({agents.length})</h1>\n <Button variant=\"major\" onClick={onOpenCreate}>\n 新建智能体\n </Button>\n </div>\n\n <div className=\"flex items-center gap-3 shrink-0\">\n <Toolbar\n searchQuery={searchQuery}\n sourceFilter={sourceFilter}\n onSearchChange={onSearchChange}\n onClearSearch={onClearSearch}\n onSourceFilterChange={onSourceFilterChange}\n onRefresh={onRefresh}\n loading={loading}\n />\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-auto\">\n <ListGrid\n agents={filteredAgents}\n onSelectAgent={onSelectAgent}\n onEditAgent={onOpenEdit}\n onDeleteAgent={onDeleteAgent}\n searchQuery={searchQuery}\n sourceFilter={sourceFilter}\n onClearSearch={onClearSearch}\n onClearFilter={() => onSourceFilterChange('all')}\n />\n </div>\n </div>\n );\n}\n\nfunction DetailView({\n agent,\n onOpenEdit,\n onBackToList,\n}: {\n agent: AgentData;\n onOpenEdit: (agentId: string) => void;\n onBackToList: () => void;\n}) {\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-8 overflow-hidden\">\n <div className=\"flex items-center justify-between py-4\">\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={onBackToList}\n className=\"text-[12px] text-[var(--text-secondary)] transition hover:text-[var(--text-primary)]\"\n >\n 智能体管理\n </button>\n <span className=\"text-[12px] text-[var(--text-muted)]\">/</span>\n <span className=\"text-[12px] font-bold text-[var(--text-primary)]\">{agent.displayName}</span>\n </div>\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-auto\">\n <div className=\"flex items-center gap-3 pb-8\">\n {agent.avatar && (agent.avatar.startsWith('/uploads/') || agent.avatar.startsWith('/avatars/') || /^https?:\\/\\//.test(agent.avatar)) ? (\n // biome-ignore lint/performance/noImgElement: runtime upload URL\n <img src={agent.avatar} alt={agent.displayName} className=\"h-10 w-10 shrink-0 rounded-full object-cover\" />\n ) : (\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-[var(--accent-primary)] text-[14px] font-medium text-white\">\n {agent.displayName.charAt(0)}\n </div>\n )}\n <h1 className=\"min-w-0 flex-1 text-[20px] font-bold text-[var(--text-primary)]\">{agent.displayName}</h1>\n <button\n type=\"button\"\n onClick={() => onOpenEdit(agent.id)}\n className=\"inline-flex h-[18px] shrink-0 items-center gap-1 text-[12px] text-[var(--text-primary)] transition hover:underline hover:underline-offset-2\"\n >\n <MaskIcon name=\"edit\" className=\"h-3.5 w-3.5\" />\n <span>编辑</span>\n </button>\n </div>\n\n <div className='border-b border-[var(--panel-border-outer)] '>\n <DetailContent agent={agent} />\n </div>\n <div className=\"mt-8\">\n <SoulConfig personality={agent.personality} agentId={agent.id} readOnly muted={false} showTitle />\n </div>\n\n <div className=\"mt-8\">\n <DetailSkillsSection agent={agent} />\n </div>\n </div>\n </div>\n );\n}\n\nfunction FormView({\n editingAgent,\n formMode,\n prefillData,\n onCancel,\n onSaveSuccess,\n onBackToDetail,\n onBackToList,\n}: {\n editingAgent: AgentData | null;\n formMode: FormMode;\n prefillData: Partial<AgentData> | null;\n onCancel: () => void;\n onSaveSuccess: () => void;\n onBackToDetail: () => void;\n onBackToList: () => void;\n}) {\n return (\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\n <FormContent\n editingAgent={editingAgent}\n formMode={formMode}\n prefillData={prefillData}\n onCancel={onCancel}\n onSaveSuccess={onSaveSuccess}\n onBackToDetail={onBackToDetail}\n onBackToList={onBackToList}\n />\n </div>\n );\n}\n\nexport function AgentManagementView({\n agents,\n filteredAgents,\n searchQuery,\n sourceFilter,\n selectedAgent,\n currentView,\n formMode,\n editingAgent,\n previousView,\n prefillData,\n loading,\n onSearchChange,\n onClearSearch,\n onSourceFilterChange,\n onRefresh,\n onSelectAgent,\n onOpenCreate,\n onOpenEdit,\n onDeleteAgent,\n onCancel,\n onSaveSuccess,\n onBackToDetail,\n onBackToList,\n}: AgentManagementViewProps) {\n let content: React.ReactNode;\n\n if (currentView === 'form') {\n content = (\n <FormView\n editingAgent={editingAgent}\n formMode={formMode}\n prefillData={prefillData}\n onCancel={onCancel}\n onSaveSuccess={onSaveSuccess}\n onBackToDetail={onBackToDetail}\n onBackToList={onBackToList}\n />\n );\n } else if (currentView === 'detail' && selectedAgent) {\n content = (\n <DetailView\n agent={selectedAgent}\n onOpenEdit={onOpenEdit}\n onBackToList={onBackToList}\n />\n );\n } else {\n content = (\n <ListView\n agents={agents}\n filteredAgents={filteredAgents}\n searchQuery={searchQuery}\n sourceFilter={sourceFilter}\n onSearchChange={onSearchChange}\n onClearSearch={onClearSearch}\n onSourceFilterChange={onSourceFilterChange}\n onRefresh={onRefresh}\n onSelectAgent={onSelectAgent}\n onOpenCreate={onOpenCreate}\n onOpenEdit={onOpenEdit}\n onDeleteAgent={onDeleteAgent}\n loading={loading}\n />\n );\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\n {content}\n </div>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useAgentData, type AgentData } from '@/hooks/useAgentData';\nimport type { FormMode, PanelView } from '../types';\nimport { filterAgents, type AgentSourceFilter } from '../utils';\n\nexport interface UsePanelStateResult {\n agents: AgentData[];\n filteredAgents: AgentData[];\n searchQuery: string;\n sourceFilter: AgentSourceFilter;\n selectedAgentId: string | null;\n selectedAgent: AgentData | null;\n currentView: PanelView;\n formMode: FormMode;\n editingAgentId: string | null;\n editingAgent: AgentData | null;\n previousView: PanelView | null;\n prefillData: Partial<AgentData> | null;\n setSearchQuery: (query: string) => void;\n setSourceFilter: (filter: AgentSourceFilter) => void;\n setSelectedAgentId: (id: string | null) => void;\n setCurrentView: (view: PanelView) => void;\n setFormMode: (mode: FormMode) => void;\n setEditingAgentId: (id: string | null) => void;\n setPreviousView: (view: PanelView | null) => void;\n handleSelectAgent: (agentId: string) => void;\n handleOpenCreate: () => void;\n handleOpenEdit: (agentId: string) => void;\n handleCancel: () => void;\n refresh: () => Promise<AgentData[]>;\n prefillAgent: (data: Partial<AgentData>) => void;\n}\n\nexport function usePanelState(): UsePanelStateResult {\n const { agents = [], refresh } = useAgentData();\n const [searchQuery, setSearchQuery] = useState('');\n const [sourceFilter, setSourceFilter] = useState<AgentSourceFilter>('all');\n const [selectedAgentId, setSelectedAgentId] = useState<string | null>(null);\n const [currentView, setCurrentView] = useState<PanelView>('list');\n const [formMode, setFormMode] = useState<FormMode>('create');\n const [editingAgentId, setEditingAgentId] = useState<string | null>(null);\n const [previousView, setPreviousView] = useState<PanelView | null>(null);\n const [prefillData, setPrefillData] = useState<Partial<AgentData> | null>(null);\n\n const filteredAgents = useMemo(() => filterAgents(agents, searchQuery, sourceFilter), [agents, searchQuery, sourceFilter]);\n\n const selectedAgent = useMemo(() => {\n if (!selectedAgentId) return null;\n return agents.find((agent) => agent.id === selectedAgentId) ?? null;\n }, [agents, selectedAgentId]);\n\n const editingAgent = useMemo(() => {\n if (!editingAgentId) return null;\n return agents.find((agent) => agent.id === editingAgentId) ?? null;\n }, [agents, editingAgentId]);\n\n const handleSelectAgent = useCallback((agentId: string) => {\n setSelectedAgentId(agentId);\n setPreviousView(currentView);\n setCurrentView('detail');\n }, [currentView]);\n\n const handleOpenCreate = useCallback(() => {\n setEditingAgentId(null);\n setFormMode('create');\n setPreviousView(currentView);\n setCurrentView('form');\n }, [currentView]);\n\n const handleOpenEdit = useCallback((agentId: string) => {\n setEditingAgentId(agentId);\n setSelectedAgentId(agentId);\n setFormMode('edit');\n setPreviousView(currentView);\n setCurrentView('form');\n }, [currentView]);\n\n const handleCancel = useCallback(() => {\n if (previousView) {\n setCurrentView(previousView);\n setPreviousView(null);\n } else {\n setCurrentView('list');\n }\n setEditingAgentId(null);\n setPrefillData(null);\n }, [previousView]);\n\n const prefillAgent = useCallback((data: Partial<AgentData>) => {\n setPrefillData(data);\n setFormMode('create');\n setPreviousView(currentView);\n setCurrentView('form');\n }, [currentView]);\n\n return {\n agents,\n filteredAgents,\n searchQuery,\n sourceFilter,\n selectedAgentId,\n selectedAgent,\n currentView,\n formMode,\n editingAgentId,\n editingAgent,\n previousView,\n prefillData,\n setSearchQuery,\n setSourceFilter,\n setSelectedAgentId,\n setCurrentView,\n setFormMode,\n setEditingAgentId,\n setPreviousView,\n handleSelectAgent,\n handleOpenCreate,\n handleOpenEdit,\n handleCancel,\n refresh,\n prefillAgent,\n };\n}","import { useCallback, useEffect } from 'react';\nimport { AgentManagementView } from './AgentManagementView';\nimport { usePanelState } from './hooks/usePanelState';\nimport type { PanelView } from './types';\nimport { useConfirm } from '@/components/useConfirm';\nimport { apiFetch } from '@/utils/api-client';\nimport { useToastStore } from '@/stores/toastStore';\nimport type { AgentData } from '@/hooks/useAgentData';\n\ninterface AgentManagementProps {\n prefillData?: Partial<AgentData> | null;\n onPrefillConsumed?: () => void;\n onViewChange?: (view: PanelView) => void;\n}\n\nexport function AgentManagement({ prefillData: externalPrefill, onPrefillConsumed, onViewChange }: AgentManagementProps = {}) {\n const state = usePanelState();\n const confirm = useConfirm();\n const addToast = useToastStore((s) => s.addToast);\n\n // Sync external prefill into panel state\n useEffect(() => {\n if (externalPrefill) {\n state.prefillAgent(externalPrefill);\n onPrefillConsumed?.();\n }\n }, [externalPrefill]);\n\n // Notify parent of view changes\n useEffect(() => {\n onViewChange?.(state.currentView);\n }, [state.currentView, onViewChange]);\n\n const handleOpenEdit = useCallback((agentId: string) => {\n state.handleOpenEdit(agentId);\n }, [state]);\n\n const handleDeleteAgent = useCallback(\n async (agentId: string) => {\n const agent = state.agents.find((a) => a.id === agentId);\n if (!agent) return;\n\n const confirmed = await confirm({\n title: '确认删除智能体',\n message: `确定要删除智能体「${agent.displayName}」吗?删除后将不可恢复。`,\n confirmLabel: '删除',\n cancelLabel: '取消',\n });\n if (!confirmed) return;\n\n try {\n const res = await apiFetch(`/api/agents/${encodeURIComponent(agentId)}`, { method: 'DELETE' });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n addToast({ type: 'success', title: '删除成功', message: `智能体「${agent.displayName}」已删除`, duration: 2600 });\n await state.refresh();\n } catch {\n addToast({ type: 'error', title: '删除失败', message: '智能体删除失败,请稍后重试', duration: 2600 });\n }\n },\n [state, confirm],\n );\n\n const handleBackToDetail = useCallback(() => {\n state.setCurrentView('detail');\n }, [state]);\n\n const handleSaveSuccess = useCallback(() => {\n state.handleCancel();\n void state.refresh();\n }, [state]);\n\n const handleBackToList = useCallback(() => {\n state.setCurrentView('list');\n }, [state]);\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <AgentManagementView\n agents={state.agents}\n filteredAgents={state.filteredAgents}\n searchQuery={state.searchQuery}\n sourceFilter={state.sourceFilter}\n selectedAgent={state.selectedAgent}\n currentView={state.currentView}\n formMode={state.formMode}\n editingAgent={state.editingAgent}\n previousView={state.previousView}\n prefillData={state.prefillData}\n onSearchChange={state.setSearchQuery}\n onClearSearch={() => state.setSearchQuery('')}\n onSourceFilterChange={state.setSourceFilter}\n onRefresh={state.refresh}\n onSelectAgent={state.handleSelectAgent}\n onOpenCreate={state.handleOpenCreate}\n onOpenEdit={handleOpenEdit}\n onDeleteAgent={handleDeleteAgent}\n onCancel={state.handleCancel}\n onSaveSuccess={handleSaveSuccess}\n onBackToDetail={handleBackToDetail}\n onBackToList={handleBackToList}\n />\n </div>\n );\n}","export type ExpertCategory = 'all' | 'insight' | 'finance' | 'product' | 'business' | 'office';\n\nexport const EXPERT_CATEGORY_LABELS: Record<Exclude<ExpertCategory, 'all'>, string> = {\n insight: '洞察研究',\n finance: '金融服务',\n product: '产品研发',\n business: '商务销售',\n office: '通用办公',\n};\n\nexport interface Expert {\n expertId: string;\n displayName: string;\n nickname: string;\n avatar: string;\n category: 'insight' | 'finance' | 'product' | 'business' | 'office';\n mentionPatterns: string[];\n roleDescription: string;\n personality: string;\n strengths: string[];\n skills?: string[];\n visibility: 'public' | 'private';\n defaultModel: string;\n providerProfileId: string;\n}\n\nexport interface InvitedExpert {\n expertId: string;\n displayName: string;\n nickname: string;\n avatar: string;\n category: 'insight' | 'finance' | 'product' | 'business' | 'office';\n mentionPatterns: string[];\n roleDescription: string;\n invitedAt: number;\n}\n\nexport interface InvitedExpertsResponse {\n threadId: string;\n invitedExperts: InvitedExpert[];\n total: number;\n}\n\nexport interface DuplicateResponse {\n ok: boolean;\n agent: {\n expertId: string;\n displayName: string;\n };\n}\n\nexport const EXPERT_CATEGORIES: Array<{ id: ExpertCategory; label: string }> = [\n { id: 'all', label: '全部' },\n { id: 'insight', label: '洞察研究' },\n { id: 'finance', label: '金融服务' },\n { id: 'product', label: '产品研发' },\n { id: 'business', label: '商务销售' },\n { id: 'office', label: '通用办公' },\n];","import { Expert, EXPERT_CATEGORY_LABELS } from '../types/expert';\n\ninterface ExpertCardProps {\n expert: Expert;\n onInvoke: (expertId: string) => void;\n onAdd: (expert: Expert) => void;\n}\n\nexport function ExpertCard({ expert, onInvoke, onAdd }: ExpertCardProps) {\n return (\n <article\n className=\"ui-card ui-card-hover group relative flex h-[196px] cursor-pointer flex-col rounded-[16px] border border-[#e6e6e6] bg-white p-6\"\n onClick={() => onInvoke(expert.expertId)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onInvoke(expert.expertId);\n }\n }}\n role=\"button\"\n tabIndex={0}\n aria-label={`召唤智能体 ${expert.displayName}`}\n >\n <div className=\"mb-4 flex items-start gap-3\">\n <div className=\"h-12 w-12 shrink-0 overflow-hidden rounded-full\">\n <img src={expert.avatar} alt={expert.displayName} className=\"h-full w-full object-cover\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate text-[14px] font-semibold text-[var(--text-primary)]\">{expert.displayName}</h3>\n <div className=\"mt-1.5 flex flex-wrap gap-1\">\n <span\n className=\"inline-flex h-[18px] items-center rounded px-[6px] text-[11px] leading-[18px] font-medium\"\n style={{ backgroundColor: '#E6E6E6', color: 'rgba(25, 25, 25, 0.85)' }}\n >\n {EXPERT_CATEGORY_LABELS[expert.category]}\n </span>\n </div>\n </div>\n </div>\n\n {expert.roleDescription ? (\n <p className=\"line-clamp-2 mb-4 flex-1 text-[12px] leading-relaxed text-[var(--text-secondary)]\">\n {expert.roleDescription}\n </p>\n ) : (\n <p className=\"line-clamp-2 mb-4 flex-1 text-[12px] leading-relaxed text-[var(--text-muted)]\">暂无描述</p>\n )}\n\n <div\n className={`absolute bottom-6 left-6 right-6 flex items-center gap-4 transition-opacity opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto group-focus-within:opacity-100 group-focus-within:pointer-events-auto`}\n >\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onInvoke(expert.expertId);\n }}\n className=\"bg-transparent p-0 text-[14px] font-normal text-[var(--text-accent)] hover:underline\"\n >\n 立即召唤\n </button>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onAdd(expert);\n }}\n className=\"bg-transparent p-0 text-[14px] font-normal text-[var(--text-accent)] hover:underline\"\n >\n 添加\n </button>\n </div>\n </article>\n );\n}","import { Expert } from '../types/expert';\nimport { ExpertCard } from './ExpertCard';\nimport { EmptyDataState } from '@/components/shared/EmptyDataState';\nimport { NoSearchResultsState } from '@/components/shared/NoSearchResultsState';\n\ninterface ExpertCardGridProps {\n experts: Expert[];\n onInvoke: (expertId: string) => void;\n onAdd: (expert: Expert) => void;\n searchQuery?: string;\n onClearSearch?: () => void;\n}\n\nexport function ExpertCardGrid({ experts, onInvoke, onAdd, searchQuery = '', onClearSearch }: ExpertCardGridProps) {\n if (experts.length === 0) {\n if (searchQuery.trim()) {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <NoSearchResultsState onClear={onClearSearch} />\n </div>\n );\n }\n return (\n <div className=\"flex items-center justify-center h-full\">\n <EmptyDataState title=\"暂无相关专家\" />\n </div>\n );\n }\n\n return (\n <div className=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4\">\n {experts.map((expert) => (\n <div key={expert.expertId} className=\"w-full\">\n <ExpertCard\n expert={expert}\n onInvoke={onInvoke}\n onAdd={onAdd}\n />\n </div>\n ))}\n </div>\n );\n}","'use client';\n\nimport { useState, useMemo } from 'react';\nimport { AppModal } from '../../AppModal';\nimport { useChatStore } from '@/stores/chatStore';\nimport { normalizeStoredThreadTitleOrNull } from '@/components/thread-sidebar/thread-title';\nimport { formatRelativeTime } from '@/components/thread-sidebar/thread-utils';\nimport { useAgentData } from '@/hooks/useAgentData';\nimport { useExpertCatalog } from '@/hooks/useExpertCatalog';\nimport { Button } from '@/components/shared/Button';\nimport type { SelectSessionModalProps } from '../types/session';\n\nconst FALLBACK_AVATAR = '/avatars/codex.png';\n\nfunction resolveAvatarUrl(rawAvatar?: string): string | null {\n const avatar = rawAvatar?.trim();\n if (!avatar) return null;\n if (avatar.startsWith('/uploads/')) return `/uploads/${avatar.replace('/uploads/', '')}`;\n if (avatar.startsWith('/')) return avatar;\n return null;\n}\n\nexport function SelectSessionModal({ open, onClose, expertId, expertMentionPattern, onConfirm, onCreateNew }: SelectSessionModalProps) {\n const threads = useChatStore((s) => s.threads);\n const { agents } = useAgentData();\n const { getExpertById } = useExpertCatalog();\n const agentById = useMemo(() => new Map(agents.map((agent) => [agent.id, agent])), [agents]);\n\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [searchQuery, setSearchQuery] = useState('');\n\n const filteredThreads = useMemo(() => {\n const query = searchQuery.toLowerCase();\n return threads.filter(\n (t) =>\n t.id !== 'default' &&\n (!query ||\n (normalizeStoredThreadTitleOrNull(t.title)?.toLowerCase() ?? '').includes(query) ||\n t.id.toLowerCase().includes(query))\n );\n }, [threads, searchQuery]);\n\n const displayOptions = useMemo(() => {\n return filteredThreads.map((thread) => {\n const participants = Array.isArray(thread.participants) ? thread.participants : [];\n const isInvited = participants.includes(expertId);\n const participantNames = participants\n .map((participantId) => agentById.get(participantId)?.displayName ?? getExpertById(participantId)?.displayName ?? participantId)\n .filter((name) => !!name.trim());\n const subtitle = participantNames.length > 0 ? participantNames.join(',') : '通用助手';\n const avatarSources = participants.slice(0, 4).map(\n (participantId) =>\n resolveAvatarUrl(agentById.get(participantId)?.avatar ?? getExpertById(participantId)?.avatar) ?? FALLBACK_AVATAR,\n );\n return {\n id: thread.id,\n label: normalizeStoredThreadTitleOrNull(thread.title) ?? '未命名对话',\n subtitle,\n avatarSources,\n timeText: formatRelativeTime(Number(thread.lastActiveAt) || 0, true),\n isInvited,\n };\n });\n }, [filteredThreads, agentById, expertId, getExpertById]);\n\n const handleConfirm = () => {\n if (selectedId) {\n onConfirm(selectedId);\n onClose();\n }\n };\n\n const handleCreateNew = () => {\n onCreateNew();\n onClose();\n };\n\n return (\n <AppModal\n open={open}\n onClose={onClose}\n title=\"选择会话\"\n panelStyle={{ width: 680 }}\n panelClassName=\"rounded-2xl\"\n bodyClassName=\"p-0\"\n >\n <div className=\"flex flex-col gap-5 mt-4\">\n {/* Controls Row */}\n <div className=\"flex items-center gap-3\">\n {/* Channel Select - hidden for now */}\n <div className=\"hidden w-[176px] h-7 px-3 rounded-[6px] border border-[#D7DEE8] bg-white cursor-pointer\">\n <span className=\"text-xs font-medium text-[#2D3643]\">全部渠道</span>\n <svg className=\"w-4 h-4 text-[#8D97A6]\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n </div>\n\n {/* Search Box */}\n <div className=\"flex-1 flex items-center gap-2 h-7 px-3 rounded-[6px] border border-[#D7DEE8] bg-white\">\n <svg className=\"w-3.5 h-3.5 text-[#A4ADBA]\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"M21 21l-4.35-4.35\" />\n </svg>\n <input\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder=\"搜索会话名称或描述\"\n className=\"flex-1 text-xs text-[#A4ADBA] bg-transparent outline-none\"\n />\n </div>\n </div>\n\n {/* Session List */}\n <div className=\"flex flex-col gap-2 overflow-y-auto max-h-[340px]\">\n {displayOptions.length === 0 ? (\n <div className=\"flex items-center justify-center h-20 text-[#667085] text-sm\">\n 暂无相关会话\n </div>\n ) : (\n displayOptions.map((option) => {\n const selected = option.id === selectedId;\n return (\n <button\n key={option.id}\n type=\"button\"\n onClick={() => setSelectedId(option.id)}\n className={[\n 'flex w-full items-start gap-3 rounded-[8px] px-6 transition',\n selected\n ? 'border-[1.5px] border-[rgba(20,118,255,1)] bg-white'\n : 'border border-[rgba(240,240,240,1)] bg-[rgba(250,250,250,1)] hover:border-[var(--connector-tab-border-hover)] hover:bg-[var(--connector-tab-bg-hover)]',\n ].join(' ')}\n style={{ height: '68px', paddingTop: 12, paddingBottom: 12 }}\n >\n {/* Avatar */}\n <div className=\"relative h-8 w-8 shrink-0\">\n {option.avatarSources.length <= 1 ? (\n <img\n src={option.avatarSources[0] ?? FALLBACK_AVATAR}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"h-8 w-8 rounded-full object-cover\"\n />\n ) : option.avatarSources.length === 2 ? (\n <>\n <img\n src={option.avatarSources[0] ?? FALLBACK_AVATAR}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"absolute left-[1px] top-[6px] h-5 w-5 rounded-full object-cover\"\n />\n <img\n src={option.avatarSources[1] ?? FALLBACK_AVATAR}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"absolute left-[11px] top-[6px] h-5 w-5 rounded-full object-cover\"\n />\n </>\n ) : option.avatarSources.length === 3 ? (\n <>\n <img\n src={option.avatarSources[0] ?? FALLBACK_AVATAR}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"absolute left-[8px] top-0 h-4 w-4 rounded-full object-cover\"\n />\n <img\n src={option.avatarSources[1] ?? FALLBACK_AVATAR}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"absolute left-0 top-[16px] h-4 w-4 rounded-full object-cover\"\n />\n <img\n src={option.avatarSources[2] ?? FALLBACK_AVATAR}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"absolute left-[16px] top-[16px] h-4 w-4 rounded-full object-cover\"\n />\n </>\n ) : (\n <>\n <img\n src={option.avatarSources[0] ?? FALLBACK_AVATAR}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"absolute left-0 top-0 h-4 w-4 rounded-full object-cover\"\n />\n <img\n src={option.avatarSources[1] ?? FALLBACK_AVATAR}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"absolute left-[16px] top-0 h-4 w-4 rounded-full object-cover\"\n />\n <img\n src={option.avatarSources[2] ?? FALLBACK_AVATAR}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"absolute left-0 top-[16px] h-4 w-4 rounded-full object-cover\"\n />\n <img\n src={option.avatarSources[3] ?? FALLBACK_AVATAR}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"absolute left-[16px] top-[16px] h-4 w-4 rounded-full object-cover\"\n />\n </>\n )}\n </div>\n\n {/* Content */}\n <div className=\"flex flex-col items-start min-w-0 flex-1 self-start\">\n <div className=\"flex items-center justify-between gap-2 w-full\">\n <span className=\"block min-w-0 truncate text-[14px] font-semibold leading-5 text-[#344054]\">\n {option.label}\n </span>\n <span className=\"shrink-0 text-[14px] leading-5 text-[#344054]\">{option.timeText}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"truncate text-[12px] leading-5 text-[#667085]\">{option.subtitle}</div>\n {option.isInvited && (\n <span className=\"shrink-0 text-[12px] leading-5 text-[#16A34A] font-medium\">已邀请</span>\n )}\n </div>\n </div>\n </button>\n );\n })\n )}\n </div>\n\n {/* Footer */}\n <div className=\"flex items-center justify-end gap-2 pb-6\">\n <Button variant=\"default\" size=\"sm\" onClick={onClose}>\n 取消\n </Button>\n <Button variant=\"default\" size=\"sm\" onClick={handleCreateNew}>\n 新建会话\n </Button>\n <Button variant=\"major\" size=\"sm\" onClick={handleConfirm} disabled={!selectedId}>\n 确定\n </Button>\n </div>\n </div>\n </AppModal>\n );\n}\n","import { useState, useMemo, useCallback } from 'react';\nimport { apiFetch } from '@/utils/api-client';\nimport type { Expert, ExpertCategory, InvitedExpertsResponse } from '../types/expert';\n\ninterface UseExpertsOptions {\n threadId?: string;\n}\n\nexport function useExperts(options: UseExpertsOptions = {}) {\n const { threadId } = options;\n const [category, setCategory] = useState<ExpertCategory>('all');\n const [experts, setExperts] = useState<Expert[]>([]);\n const [invitedExpertIds, setInvitedExpertIds] = useState<string[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [searchQuery, setSearchQuery] = useState('');\n\n // Fetch experts list from API\n const fetchExperts = useCallback(async (cat?: ExpertCategory) => {\n setIsLoading(true);\n setError(null);\n try {\n const params = cat && cat !== 'all' ? `?category=${cat}` : '';\n const response = await apiFetch(`/api/experts${params}`);\n if (!response.ok) throw new Error('Failed to fetch experts');\n const data = await response.json();\n setExperts(data.experts ?? []);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Unknown error');\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n // Fetch invited experts for current thread\n const fetchInvitedExperts = useCallback(async () => {\n if (!threadId) return;\n try {\n const response = await apiFetch(`/api/threads/${threadId}/experts`);\n if (!response.ok) throw new Error('Failed to fetch invited experts');\n const data: InvitedExpertsResponse = await response.json();\n setInvitedExpertIds(data.invitedExperts.map((e) => e.expertId));\n } catch (err) {\n // Silently fail for invited experts\n console.error('Failed to fetch invited experts:', err);\n }\n }, [threadId]);\n\n // Invite an expert to the thread\n const inviteExpert = useCallback(\n async (expertId: string, targetThreadId?: string) => {\n const tid = targetThreadId ?? threadId;\n if (!tid) return false;\n try {\n const response = await apiFetch(`/api/threads/${tid}/experts/${expertId}/invite`, {\n method: 'POST',\n });\n if (!response.ok) {\n const err = await response.json();\n throw new Error(err.message || 'Failed to invite expert');\n }\n await fetchInvitedExperts();\n return true;\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Unknown error');\n return false;\n }\n },\n [threadId, fetchInvitedExperts],\n );\n\n // Remove an expert from the thread\n const removeExpert = useCallback(\n async (expertId: string) => {\n if (!threadId) return false;\n try {\n const response = await apiFetch(`/api/threads/${threadId}/experts/${expertId}`, {\n method: 'DELETE',\n });\n if (!response.ok) {\n const err = await response.json();\n throw new Error(err.message || 'Failed to remove expert');\n }\n await fetchInvitedExperts();\n return true;\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Unknown error');\n return false;\n }\n },\n [threadId, fetchInvitedExperts],\n );\n\n const filteredExperts = useMemo(() => {\n let result = experts;\n if (category !== 'all') {\n result = result.filter((e) => e.category === category);\n }\n if (searchQuery.trim()) {\n const q = searchQuery.trim().toLowerCase();\n result = result.filter(\n (e) =>\n e.displayName.toLowerCase().includes(q) ||\n e.roleDescription.toLowerCase().includes(q) ||\n (e.skills && e.skills.some((s) => s.toLowerCase().includes(q))),\n );\n }\n return result;\n }, [experts, category, searchQuery]);\n\n return {\n experts: filteredExperts,\n allExperts: experts,\n category,\n setCategory,\n invitedExpertIds,\n isLoading,\n error,\n fetchExperts,\n fetchInvitedExperts,\n inviteExpert,\n removeExpert,\n searchQuery,\n setSearchQuery,\n };\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { ExpertCardGrid } from './components/ExpertCardGrid';\nimport { SelectSessionModal } from './components/SelectSessionModal';\nimport { useExperts } from './hooks/useExperts';\nimport { useChatStore } from '@/stores/chatStore';\nimport { apiFetch } from '@/utils/api-client';\nimport { EXPERT_CATEGORIES, type Expert } from './types/expert';\nimport { SearchInput } from '@/components/shared/SearchInput';\nimport { RefreshButton } from '@/components/shared/RefreshButton';\nimport { buildResolvedMention } from '@/components/chat-input/utils/helpers';\n\ninterface ExpertsPanelProps {\n onAddExpert?: (expert: Expert) => void;\n}\n\nexport function ExpertsPanel({ onAddExpert }: ExpertsPanelProps = {}) {\n const navigate = useNavigate();\n const currentThreadId = useChatStore((s) => s.currentThreadId);\n const { experts, allExperts, category, setCategory, invitedExpertIds, isLoading, fetchExperts, inviteExpert, searchQuery, setSearchQuery } =\n useExperts({ threadId: currentThreadId });\n\n const setCurrentThread = useChatStore((s) => s.setCurrentThread);\n const setPendingChatInsert = useChatStore((s) => s.setPendingChatInsert);\n\n useEffect(() => {\n void fetchExperts();\n }, [fetchExperts]);\n\n const [modalOpen, setModalOpen] = useState(false);\n const [selectedExpertId, setSelectedExpertId] = useState<string | null>(null);\n const [selectedExpertMention, setSelectedExpertMention] = useState<string | null>(null);\n\n const handleInvoke = (expertId: string) => {\n const expert = experts.find((e) => e.expertId === expertId);\n setSelectedExpertId(expertId);\n setSelectedExpertMention(expert ? buildResolvedMention(expert) : null);\n setModalOpen(true);\n };\n\n const handleConfirm = (threadId: string) => {\n if (selectedExpertId) {\n void inviteExpert(selectedExpertId, threadId).then((ok) => {\n if (ok && selectedExpertMention) {\n setPendingChatInsert({\n threadId,\n text: `${selectedExpertMention} `,\n replaceTrailingMentionTrigger: true,\n suppressMentionMenu: true,\n mentionRefs: [{ catId: selectedExpertId, mention: selectedExpertMention }],\n });\n setCurrentThread(threadId);\n navigate(`/thread/${threadId}`);\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('office-claw:threads-refresh'));\n }\n }\n });\n }\n setModalOpen(false);\n };\n\n const handleCreateNew = async () => {\n if (!selectedExpertId || !selectedExpertMention) return;\n try {\n const response = await apiFetch('/api/threads', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({}),\n });\n if (!response.ok) throw new Error('Failed to create thread');\n const thread = await response.json();\n const newThreadId = thread.id;\n const ok = await inviteExpert(selectedExpertId, newThreadId);\n if (ok) {\n setPendingChatInsert({\n threadId: newThreadId,\n text: `${selectedExpertMention} `,\n replaceTrailingMentionTrigger: true,\n suppressMentionMenu: true,\n mentionRefs: [{ catId: selectedExpertId, mention: selectedExpertMention }],\n });\n setCurrentThread(newThreadId);\n navigate(`/thread/${newThreadId}`);\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('office-claw:threads-refresh'));\n }\n }\n } catch (err) {\n console.error('Failed to create thread:', err);\n }\n setModalOpen(false);\n };\n\n const handleAdd = (expert: Expert) => {\n onAddExpert?.(expert);\n };\n\n return (\n <div className=\"ui-page-shell gap-6 overflow-hidden\">\n <div className=\"flex flex-col gap-4\">\n <div className=\"ui-page-header-inline items-start\">\n <div className=\"flex flex-wrap items-center gap-4\">\n {EXPERT_CATEGORIES.map((catItem) => {\n return (\n <div key={catItem.id} className=\"flex items-center\">\n {catItem.id !== 'all' ? (\n <div aria-hidden=\"true\" className=\"mr-4 h-4 w-px self-center bg-[#dbdbdb]\" />\n ) : null}\n <button\n type=\"button\"\n onClick={() => setCategory(catItem.id)}\n className={`inline-flex min-h-7 items-center leading-none text-sm transition-colors ${\n category === catItem.id\n ? 'font-semibold text-[var(--text-primary)]'\n : 'text-[var(--text-muted)] hover:text-[var(--text-primary)]'\n }`}\n >\n {catItem.label}\n </button>\n </div>\n );\n })}\n </div>\n </div>\n\n <div className=\"flex items-center justify-between\">\n <h1 className=\"ui-page-title\">智能体广场({allExperts.length})</h1>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <SearchInput\n value={searchQuery}\n onChange={(value) => setSearchQuery(value)}\n onClear={() => setSearchQuery('')}\n placeholder=\"搜索专家名称、职责或技能\"\n aria-label=\"搜索专家\"\n clearAriaLabel=\"清除搜索\"\n wrapperClassName=\"flex-1\"\n />\n <RefreshButton\n onClick={() => { void fetchExperts(); }}\n disabled={isLoading}\n aria-label=\"刷新专家列表\"\n />\n </div>\n </div>\n\n <div className=\"flex-1 min-h-0 overflow-auto\">\n {isLoading ? (\n <div className=\"flex items-center justify-center h-full\">\n <span className=\"text-[var(--text-muted)]\">加载中...</span>\n </div>\n ) : (\n <ExpertCardGrid\n experts={experts}\n onInvoke={handleInvoke}\n onAdd={handleAdd}\n searchQuery={searchQuery}\n onClearSearch={() => setSearchQuery('')}\n />\n )}\n </div>\n\n <SelectSessionModal\n open={modalOpen}\n onClose={() => setModalOpen(false)}\n expertId={selectedExpertId || ''}\n expertMentionPattern={selectedExpertMention || undefined}\n onConfirm={handleConfirm}\n onCreateNew={handleCreateNew}\n />\n </div>\n );\n}\n","/*\n * *\n * * Copyright (C) Huawei Technologies Co., Ltd. 2026. All rights reserved.\n *\n */\n\n'use client';\n\nimport { useEffect, useState } from 'react';\nimport { AgentManagement } from './agent-management/AgentManagement';\nimport { ExpertsPanel } from './experts-panel/ExpertsPanel';\nimport type { PanelView } from './agent-management/types';\nimport type { AgentData } from '@/hooks/useAgentData';\n\ntype RootTabKey = 'agents' | 'experts';\n\nconst ROOT_TABS: Array<{ id: RootTabKey; label: string }> = [\n { id: 'agents', label: '智能体管理' },\n { id: 'experts', label: '智能体广场' },\n];\n\nexport function AgentsPanel() {\n const [activeTab, setActiveTab] = useState<RootTabKey>('agents');\n const [prefillData, setPrefillData] = useState<Partial<AgentData> | null>(null);\n const [agentPanelView, setAgentPanelView] = useState<PanelView>('list');\n\n useEffect(() => {\n const handleSwitchToAgents = () => setActiveTab('agents');\n window.addEventListener('agents-panel:switch-to-agents', handleSwitchToAgents as EventListener);\n return () => {\n window.removeEventListener('agents-panel:switch-to-agents', handleSwitchToAgents as EventListener);\n };\n }, []);\n\n const handleAddExpert = (expert: Partial<AgentData>) => {\n setPrefillData({\n ...expert,\n creationSource: 'experts-plaza' as const,\n });\n setActiveTab('agents');\n };\n\n // Hide root tabs when in form or detail view within agent management\n const showRootTabs = activeTab === 'experts' || (activeTab === 'agents' && agentPanelView === 'list');\n\n return (\n <div className=\"ui-page-shell\">\n {showRootTabs && (\n <>\n <div className=\"flex shrink-0 items-center gap-6 px-1\">\n {ROOT_TABS.map((tab) => {\n const isActive = tab.id === activeTab;\n\n return (\n <button\n key={tab.id}\n type=\"button\"\n data-testid={`agents-panel-tab-${tab.id}`}\n aria-pressed={isActive}\n onClick={() => setActiveTab(tab.id)}\n className={`relative pb-2 text-[14px] transition ${\n isActive\n ? 'font-semibold text-[var(--text-primary)]'\n : 'font-medium text-[var(--text-label-secondary)] hover:text-[var(--text-secondary)]'\n }`}\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n\n <div data-testid=\"agents-panel-divider\" className=\"mb-6 h-px w-full shrink-0 bg-[var(--border-elevated)]\" />\n </>\n )}\n\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\n {activeTab === 'agents' ? (\n <AgentManagement\n prefillData={prefillData}\n onPrefillConsumed={() => setPrefillData(null)}\n onViewChange={setAgentPanelView}\n />\n ) : (\n <ExpertsPanel onAddExpert={handleAddExpert} />\n )}\n </div>\n </div>\n );\n}\n","/*\n * *\n * * Copyright (C) Huawei Technologies Co., Ltd. 2026. All rights reserved.\n *\n */\n\nimport { AgentsPanel } from '@/components/AgentsPanel';\n\nexport default function AgentsPage() {\n return (\n <div className=\"h-full overflow-hidden ui-shell-surface px-8 py-8\">\n <AgentsPanel />\n </div>\n );\n}\n"],"names":["getNameInitial","name","getNameInitialTheme","colors","index","Avatar","agent","avatar","_a","jsx","theme","Card","onClick","onEdit","onDelete","modelText","sourceText","jsxs","e","AGENT_LIST_GRID_CLASS","FORM_STEPS","TEMPLATE_PAGE_SIZE","MODEL_MENU_MAX_HEIGHT","MODEL_MENU_OFFSET","HUAWEI_PROVIDER_LABEL","RELAYCLAW_CLIENT","AGENT_NAME_VALIDATION_MESSAGE","PRESET_AVATARS","DEFAULT_PRESET_AVATAR","INSPIRATION_TEMPLATES","buildTemplateMarkdown","template","ListGrid","agents","onSelectAgent","onEditAgent","onDeleteAgent","searchQuery","sourceFilter","onClearSearch","onClearFilter","NoSearchResultsState","EmptyDataState","SOURCE_FILTER_OPTIONS","Toolbar","onSearchChange","onSourceFilterChange","onRefresh","loading","sourceMenuOpen","setSourceMenuOpen","useState","activeSourceLabel","opt","prev","isSelected","SearchInput","RefreshButton","DetailContent","imageModelText","OverflowTooltip","HelpPrompt","cachedSkillBasicInfos","getSkillBasicInfo","skillName","setSkillBasicInfo","info","setMultipleSkillBasicInfos","infos","DetailSkillsSection","skills","loadingSkills","setLoadingSkills","useEffect","missingSkills","res","apiFetch","data","next","styles","skillInfo","isLoading","NameInitialIcon","ChevronLeftIcon","props","ChevronRightIcon","MarkdownEditor","activeTab","activeWorkingDraft","editorSurfaceRef","editorTextareaRef","isPersonaEmpty","onApplyTemplate","onAfterApplyTemplate","onDraftChange","onNextTemplatePage","onPrevTemplatePage","templatePage","templatePageCount","visibleTemplates","appliedTemplateKey","showTemplates","event","MarkdownContent","Button","MarkdownEditorWrapper","useRef","setTemplatePage","setAppliedTemplateKey","handleApplyTemplate","useCallback","templateId","t","markdown","existing","k","handleAfterApplyTemplate","p","SoulConfig","personality","agentId","readOnly","muted","showTitle","titleElement","filterAgents","result","normalizedQuery","avatarSeed","normalized","hash","char","buildGeneratedAvatarDataUrl","label","svg","resolveInitialAvatar","member","getRandomPresetAvatar","randomIndex","formatAvatarUrl","API_URL","isDuplicateNameErrorMessage","message","UNAVAILABLE_MODEL_ERROR_PATTERN","MISSING_PROVIDER_ERROR_PATTERN","normalizeAgentSaveErrorMessage","trimmed","DEFAULT_MODEL_ICON","ChevronDownIcon","ModelIcon","item","imageSrc","ModelSelectValueDraft","placeholder","ModelSelectTriggerIcon","ModelSelectDropdown","groups","selectedId","searchPlaceholder","allowClear","onSelect","onClear","query","setQuery","filteredGroups","useMemo","group","value","SparklesIcon","MaskIcon","BasicInfoSection","avatarError","displayAvatar","draftDefaultModel","draftImageModel","draftDescription","draftName","fileInputRef","inlineNameError","loadingModels","modelGroups","modelMenuOpen","modelMenuPosition","modelMenuRef","modelTriggerRef","modelError","loadingImageModels","imageModelGroups","imageModelMenuOpen","imageModelMenuPosition","imageModelMenuRef","imageModelTriggerRef","missingImageModel","onAvatarUpload","onDescriptionChange","onNameChange","onRandomAvatar","onSelectModel","onToggleModelMenu","onSelectImageModel","onClearImageModel","onToggleImageModelMenu","selectedModel","selectedImageModel","openAbove","imageModelOpenAbove","uploadingAvatar","Textarea","current","max","Fragment","createPortal","FormFooter","error","formMode","isConfirmDisabled","onCancel","onSave","saving","FormHeader","displayName","onBackToDetail","onBackToList","showWarning","setShowWarning","Alert","useInstallStatus","installStatus","setInstallStatus","statusTimers","setInstallStatusWithTimer","slug","status","timer","clearInstallStatus","PAGE_SIZE","CATEGORY_MAP","normalizeCategory","cat","resolveCategoryParam","category","zh","useSkillSearch","searchResults","setSearchResults","searchLoading","setSearchLoading","loadingMore","setLoadingMore","currentPage","setCurrentPage","categories","setCategories","activeCategory","setActiveCategory","requestSeqRef","activeAbortRef","buildSkillsUrl","page","params","categoryParam","loadPage","append","requestId","controller","setLoadingFn","loadCategories","sorted","left","right","handleLoadMore","useSkillInstall","onInstallSuccess","onInstallError","owner","repo","skill","skillDescription","skillVersion","notifySkillOptionsChanged","useToastStore","detail","INSTALLED_TAB","SKILL_PLAZA_TAB","ALL_CATEGORY","UNCATEGORIZED","ALL_SKILL_SOURCES","SKILL_SCOPE_TABS","CATEGORY_FILTER_ARIA_LABEL","skillMatchesQuery","lowered","markSkillInstalled","changed","SkillSelectorDrawer","open","selectedSkills","skillBasicInfos","onConfirm","onClose","setActiveTab","draftSelected","setDraftSelected","setSkills","internalSkillBasicInfos","setInternalSkillBasicInfos","setLoading","activeSourceScope","setActiveSourceScope","categoryMenuOpen","setCategoryMenuOpen","uploadModalOpen","setUploadModalOpen","categoryMenuRef","searchEffectReadyRef","loadMoreTriggerRef","handleInstall","skillInfoList","s","detailsMap","handleCategoryChange","handleUploadSuccess","el","observer","entries","handleKeyDown","onPointerDown","target","filteredSkills","filtered","installedCategories","cats","plazaSkills","toggleSkill","skillId","id","handleConfirm","allSkillInfos","onInstallSkill","displaySkills","hasResults","tab","skillDesc","skillCategory","isInstalled","UploadSkillModal","FormSkillsSection","editingAgent","onSkillsChange","drawerOpen","setDrawerOpen","handleRemoveSkill","skillToRemove","newSkills","newDetails","selectedSkillBasicInfos","_b","MODAL_WIDTH","MODAL_VIEWPORT_OFFSET","CARD_DETAIL_GAP","LIST_SCROLLBAR_SLOT","CONTENT_GAP","LIST_WIDTH","LIST_SCROLL_CONTAINER_WIDTH","DETAIL_WIDTH","RefreshIcon","CloseIcon","normalizeSearch","PromptDetailContent","buildItemSummary","summary","buildSearchFields","promptItemMatchesQuery","field","PromptSelectionModal","items","initialSelectedId","title","cancelLabel","confirmLabel","setSelectedId","filteredItems","hasNoMatches","selectedItem","PROMPT_SELECTION_ITEMS","FormSoulSection","templateModalOpen","setTemplateModalOpen","FormStepNav","activeStep","onStepClick","step","FORM_STEP_LOCK_MS","useFormStepScroll","scrollContainerRef","stepRefs","isManualOperating","setIsManualOperating","manualStepTimerRef","clearManualStepTimer","syncActiveStepFromScroll","container","soulNode","containerRect","scrollToStep","stepId","ref","offsetTop","nextTop","scrollToBasicTop","handleStepClick","handleScroll","useModelMenu","modelGroupCount","modelItemCount","setOpenAbove","setModelMenuPosition","updateModelMenuPosition","rect","estimatedMenuHeight","nextOpenAbove","handlePointerDown","handleEscape","useLayoutEffect","handleViewportChange","normalizeInitialModelName","parts","pickStringField","candidates","key","parseAccountRefFromModelItem","rawId","rest","splitIndex","parseModelNameFromModelItemId","accountRef","fallbackName","prefix","toModelOption","card","normalizeModel","modelLabel","providerLabel","model","protocolGroupKey","protocolGroupLabel","buildFallbackSelectedOption","effectiveAccountRef","isHuawei","groupId","HUAWEI_MAAS_GROUP_KEY","FREE_HUAWEI_MAAS_GROUP_LABEL","CUSTOM_MODEL_GROUP_LABEL","useModelSelection","editingDefaultModel","editingAccountRef","defaultToFirstModel","marketplaceModels","setMarketplaceModels","setLoadingModels","selectedModelId","setSelectedModelId","cancelled","response","body","source","normalizedEditingModel","availableModels","deduped","acc","selectionHint","matchedById","m","matchedByPair","matchedByModel","missingModel","modelId","resolveForSave","DEFAULT_MAX_SIZE","useAvatarUpload","onSuccess","maxSizeBytes","uploading","setUploading","setError","handleUpload","file","url","uploadAvatarAsset","err","autoSlug","validateAgentName","generateRandomAgentId","timestamp","random","DEFAULT_ROLE_DESCRIPTION","FormContent","prefillData","onSaveSuccess","setDraftName","setDraftDescription","draftAvatar","setDraftAvatar","setDraftDefaultModel","setDraftImageModel","setActiveWorkingDraft","setSaving","globalError","setGlobalError","nameSubmitError","setNameSubmitError","setModelError","draftSkills","setDraftSkills","draftSkillBasicInfos","setDraftSkillBasicInfos","setModelMenuOpen","setImageModelMenuOpen","basicRef","soulRef","skillsRef","nameError","editingImageAccountRef","onModelSelect","imageModels","rawImageModelGroups","onImageModelSelect","resolveImageModelForSave","total","handleAvatarUpload","selected","handleSave","resolved","resolvedAccountRef","resolvedModel","safeName","safeDescription","mentionSeed","resolvedImageModel","resolvedImageAccountRef","resolvedImageModelName","finalImageModel","finalImageAccountRef","formState","payload","buildAgentPayload","method","nextError","ListView","filteredAgents","onOpenCreate","onOpenEdit","DetailView","FormView","AgentManagementView","selectedAgent","currentView","previousView","content","usePanelState","refresh","useAgentData","setSearchQuery","setSourceFilter","selectedAgentId","setSelectedAgentId","setCurrentView","setFormMode","editingAgentId","setEditingAgentId","setPreviousView","setPrefillData","handleSelectAgent","handleOpenCreate","handleOpenEdit","handleCancel","prefillAgent","AgentManagement","externalPrefill","onPrefillConsumed","onViewChange","state","confirm","useConfirm","addToast","handleDeleteAgent","a","handleBackToDetail","handleSaveSuccess","handleBackToList","EXPERT_CATEGORY_LABELS","EXPERT_CATEGORIES","ExpertCard","expert","onInvoke","onAdd","ExpertCardGrid","experts","FALLBACK_AVATAR","resolveAvatarUrl","rawAvatar","SelectSessionModal","expertId","expertMentionPattern","onCreateNew","threads","useChatStore","getExpertById","useExpertCatalog","agentById","filteredThreads","normalizeStoredThreadTitleOrNull","displayOptions","thread","participants","isInvited","participantNames","participantId","subtitle","avatarSources","formatRelativeTime","handleCreateNew","AppModal","option","useExperts","options","threadId","setCategory","setExperts","invitedExpertIds","setInvitedExpertIds","setIsLoading","fetchExperts","fetchInvitedExperts","inviteExpert","targetThreadId","tid","removeExpert","q","ExpertsPanel","onAddExpert","navigate","useNavigate","currentThreadId","allExperts","setCurrentThread","setPendingChatInsert","modalOpen","setModalOpen","selectedExpertId","setSelectedExpertId","selectedExpertMention","setSelectedExpertMention","handleInvoke","buildResolvedMention","ok","newThreadId","handleAdd","catItem","ROOT_TABS","AgentsPanel","agentPanelView","setAgentPanelView","handleSwitchToAgents","handleAddExpert","showRootTabs","isActive","AgentsPage"],"mappings":"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"}
|