diff --git a/.gitignore b/.gitignore index 4fd1ef9e..bde62f5d 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,7 @@ offline-backend-20260512/backend/.deer-flow/* offline-backend-20260512/start_backend.sh offline-backend-20260512/stop_backend.sh offline-backend-20260512/check_backend.sh + +skills/ +hermes-agent-main/ +.gitignore diff --git a/frontend-web/src/pages/NewAgentPage.tsx b/frontend-web/src/pages/NewAgentPage.tsx index f60e7642..e64de2bc 100644 --- a/frontend-web/src/pages/NewAgentPage.tsx +++ b/frontend-web/src/pages/NewAgentPage.tsx @@ -17,6 +17,13 @@ import { } from "@/components/ai-elements/prompt-input"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { ArtifactsProvider } from "@/components/workspace/artifacts"; import { @@ -33,6 +40,7 @@ import { updateAgent, } from "@/core/agents/api"; import { useI18n } from "@/core/i18n/hooks"; +import { useModels } from "@/core/models/hooks"; import type { Skill } from "@/core/skills"; import { useSkills } from "@/core/skills/hooks"; import { useThreadStream } from "@/core/threads/hooks"; @@ -63,6 +71,8 @@ export default function NewAgentPage() { const [nameInput, setNameInput] = useState(""); const [descriptionInput, setDescriptionInput] = useState(""); const [soulInput, setSoulInput] = useState(""); + const [modelInput, setModelInput] = useState(""); + const [chatModelInput, setChatModelInput] = useState(""); const [formError, setFormError] = useState(""); const [agentId, setAgentId] = useState(""); const [agent, setAgent] = useState(null); @@ -72,6 +82,7 @@ export default function NewAgentPage() { const [isSkillSelectionTouched, setIsSkillSelectionTouched] = useState(false); const [threadPrepared, setThreadPrepared] = useState(false); const { skills, isLoading: isSkillsLoading } = useSkills(); + const { models, isLoading: isModelsLoading } = useModels(); const enabledSkills = useMemo( () => skills.filter((skill) => skill.enabled), @@ -89,12 +100,24 @@ export default function NewAgentPage() { ); }, [enabledSkills, isSkillSelectionTouched]); + // Seed both model selectors with the first available model the first time + // models load. The user can still change either independently afterwards. + useEffect(() => { + if (models.length === 0) { + return; + } + const first = models[0]!.name; + setModelInput((prev) => prev || first); + setChatModelInput((prev) => prev || first); + }, [models]); + const [thread, sendMessage] = useThreadStream({ threadId, assistantId: agentId || undefined, context: { mode: "flash", is_bootstrap: true, + model_name: chatModelInput || undefined, }, onToolEnd() { // setup_agent never actually executes in this flow — it gets @@ -140,6 +163,8 @@ export default function NewAgentPage() { name = `未命名专家-${Date.now().toString(36)}`; } + const modelOverride = modelInput.trim() || null; + if (agentId) { setIsSavingDraft(true); try { @@ -148,6 +173,7 @@ export default function NewAgentPage() { description: descriptionInput, soul: soulInput, skills: selectedSkills, + model: modelOverride, }); setAgent(updated); return updated; @@ -167,6 +193,7 @@ export default function NewAgentPage() { description: descriptionInput, soul: soulInput, skills: selectedSkills, + model: modelOverride, }); setAgentId(created.id); setAgent(created); @@ -193,6 +220,7 @@ export default function NewAgentPage() { }, [ agentId, descriptionInput, + modelInput, selectedSkills, soulInput, t.agents.nameStepCheckError, @@ -305,7 +333,28 @@ export default function NewAgentPage() { onSetupAgentReject={handleRejectSetupAgent} /> -
+
+
+ + 当前对话模型 + + +
void handleChatSubmit(text)} > @@ -354,6 +403,29 @@ export default function NewAgentPage() { />
+
+ + +

+ 该专家被使用时调用的模型。 +

+
+