Merge branch 'master' of http://192.168.0.200/knowledge-base-bj/deerflow-server into dhk-2
This commit is contained in:
commit
f4769c4046
2 files changed
+77
-1
No files matched your search
@@ -64,3 +64,7 @@ offline-backend-20260512/backend/.deer-flow/*
|
|||||||
offline-backend-20260512/start_backend.sh
|
offline-backend-20260512/start_backend.sh
|
||||||
offline-backend-20260512/stop_backend.sh
|
offline-backend-20260512/stop_backend.sh
|
||||||
offline-backend-20260512/check_backend.sh
|
offline-backend-20260512/check_backend.sh
|
||||||
|
|
||||||
|
skills/
|
||||||
|
hermes-agent-main/
|
||||||
|
.gitignore
|
||||||
@@ -17,6 +17,13 @@ import {
|
|||||||
} from "@/components/ai-elements/prompt-input";
|
} from "@/components/ai-elements/prompt-input";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { ArtifactsProvider } from "@/components/workspace/artifacts";
|
import { ArtifactsProvider } from "@/components/workspace/artifacts";
|
||||||
import {
|
import {
|
||||||
@@ -33,6 +40,7 @@ import {
|
|||||||
updateAgent,
|
updateAgent,
|
||||||
} from "@/core/agents/api";
|
} from "@/core/agents/api";
|
||||||
import { useI18n } from "@/core/i18n/hooks";
|
import { useI18n } from "@/core/i18n/hooks";
|
||||||
|
import { useModels } from "@/core/models/hooks";
|
||||||
import type { Skill } from "@/core/skills";
|
import type { Skill } from "@/core/skills";
|
||||||
import { useSkills } from "@/core/skills/hooks";
|
import { useSkills } from "@/core/skills/hooks";
|
||||||
import { useThreadStream } from "@/core/threads/hooks";
|
import { useThreadStream } from "@/core/threads/hooks";
|
||||||
@@ -63,6 +71,8 @@ export default function NewAgentPage() {
|
|||||||
const [nameInput, setNameInput] = useState("");
|
const [nameInput, setNameInput] = useState("");
|
||||||
const [descriptionInput, setDescriptionInput] = useState("");
|
const [descriptionInput, setDescriptionInput] = useState("");
|
||||||
const [soulInput, setSoulInput] = useState("");
|
const [soulInput, setSoulInput] = useState("");
|
||||||
|
const [modelInput, setModelInput] = useState<string>("");
|
||||||
|
const [chatModelInput, setChatModelInput] = useState<string>("");
|
||||||
const [formError, setFormError] = useState("");
|
const [formError, setFormError] = useState("");
|
||||||
const [agentId, setAgentId] = useState("");
|
const [agentId, setAgentId] = useState("");
|
||||||
const [agent, setAgent] = useState<Agent | null>(null);
|
const [agent, setAgent] = useState<Agent | null>(null);
|
||||||
@@ -72,6 +82,7 @@ export default function NewAgentPage() {
|
|||||||
const [isSkillSelectionTouched, setIsSkillSelectionTouched] = useState(false);
|
const [isSkillSelectionTouched, setIsSkillSelectionTouched] = useState(false);
|
||||||
const [threadPrepared, setThreadPrepared] = useState(false);
|
const [threadPrepared, setThreadPrepared] = useState(false);
|
||||||
const { skills, isLoading: isSkillsLoading } = useSkills();
|
const { skills, isLoading: isSkillsLoading } = useSkills();
|
||||||
|
const { models, isLoading: isModelsLoading } = useModels();
|
||||||
|
|
||||||
const enabledSkills = useMemo(
|
const enabledSkills = useMemo(
|
||||||
() => skills.filter((skill) => skill.enabled),
|
() => skills.filter((skill) => skill.enabled),
|
||||||
@@ -89,12 +100,24 @@ export default function NewAgentPage() {
|
|||||||
);
|
);
|
||||||
}, [enabledSkills, isSkillSelectionTouched]);
|
}, [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({
|
const [thread, sendMessage] = useThreadStream({
|
||||||
threadId,
|
threadId,
|
||||||
assistantId: agentId || undefined,
|
assistantId: agentId || undefined,
|
||||||
context: {
|
context: {
|
||||||
mode: "flash",
|
mode: "flash",
|
||||||
is_bootstrap: true,
|
is_bootstrap: true,
|
||||||
|
model_name: chatModelInput || undefined,
|
||||||
},
|
},
|
||||||
onToolEnd() {
|
onToolEnd() {
|
||||||
// setup_agent never actually executes in this flow — it gets
|
// setup_agent never actually executes in this flow — it gets
|
||||||
@@ -140,6 +163,8 @@ export default function NewAgentPage() {
|
|||||||
name = `未命名专家-${Date.now().toString(36)}`;
|
name = `未命名专家-${Date.now().toString(36)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const modelOverride = modelInput.trim() || null;
|
||||||
|
|
||||||
if (agentId) {
|
if (agentId) {
|
||||||
setIsSavingDraft(true);
|
setIsSavingDraft(true);
|
||||||
try {
|
try {
|
||||||
@@ -148,6 +173,7 @@ export default function NewAgentPage() {
|
|||||||
description: descriptionInput,
|
description: descriptionInput,
|
||||||
soul: soulInput,
|
soul: soulInput,
|
||||||
skills: selectedSkills,
|
skills: selectedSkills,
|
||||||
|
model: modelOverride,
|
||||||
});
|
});
|
||||||
setAgent(updated);
|
setAgent(updated);
|
||||||
return updated;
|
return updated;
|
||||||
@@ -167,6 +193,7 @@ export default function NewAgentPage() {
|
|||||||
description: descriptionInput,
|
description: descriptionInput,
|
||||||
soul: soulInput,
|
soul: soulInput,
|
||||||
skills: selectedSkills,
|
skills: selectedSkills,
|
||||||
|
model: modelOverride,
|
||||||
});
|
});
|
||||||
setAgentId(created.id);
|
setAgentId(created.id);
|
||||||
setAgent(created);
|
setAgent(created);
|
||||||
@@ -193,6 +220,7 @@ export default function NewAgentPage() {
|
|||||||
}, [
|
}, [
|
||||||
agentId,
|
agentId,
|
||||||
descriptionInput,
|
descriptionInput,
|
||||||
|
modelInput,
|
||||||
selectedSkills,
|
selectedSkills,
|
||||||
soulInput,
|
soulInput,
|
||||||
t.agents.nameStepCheckError,
|
t.agents.nameStepCheckError,
|
||||||
@@ -305,7 +333,28 @@ export default function NewAgentPage() {
|
|||||||
onSetupAgentReject={handleRejectSetupAgent}
|
onSetupAgentReject={handleRejectSetupAgent}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-background shrink-0 border-t px-4 py-4">
|
<div className="bg-background shrink-0 space-y-2 border-t px-4 py-4">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-muted-foreground text-xs">
|
||||||
|
当前对话模型
|
||||||
|
</span>
|
||||||
|
<Select
|
||||||
|
value={chatModelInput}
|
||||||
|
onValueChange={setChatModelInput}
|
||||||
|
disabled={isModelsLoading || thread.isLoading}
|
||||||
|
>
|
||||||
|
<SelectTrigger className="h-7 w-auto min-w-[10rem] gap-2 px-2 text-xs">
|
||||||
|
<SelectValue placeholder="选择模型" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{models.map((model) => (
|
||||||
|
<SelectItem key={model.name} value={model.name}>
|
||||||
|
{model.display_name || model.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
<PromptInput
|
<PromptInput
|
||||||
onSubmit={({ text }) => void handleChatSubmit(text)}
|
onSubmit={({ text }) => void handleChatSubmit(text)}
|
||||||
>
|
>
|
||||||
@@ -354,6 +403,29 @@ export default function NewAgentPage() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium">模型</label>
|
||||||
|
<Select
|
||||||
|
value={modelInput}
|
||||||
|
onValueChange={setModelInput}
|
||||||
|
disabled={isModelsLoading}
|
||||||
|
>
|
||||||
|
<SelectTrigger className="w-full">
|
||||||
|
<SelectValue placeholder="选择模型" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{models.map((model) => (
|
||||||
|
<SelectItem key={model.name} value={model.name}>
|
||||||
|
{model.display_name || model.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<p className="text-muted-foreground text-xs">
|
||||||
|
该专家被使用时调用的模型。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<label className="text-sm font-medium">SOUL.md</label>
|
<label className="text-sm font-medium">SOUL.md</label>
|
||||||
<Textarea
|
<Textarea
|
||||||
|
|||||||
Reference in new issue
Block a user