Skip to content

Commit f5aa346

Browse files
committed
Merge remote-tracking branch 'origin/develop' into xyc/app_config_bugfix
# Conflicts: # frontend/app/[locale]/setup/models/components/model/ModelAddDialog.tsx
2 parents 4a70a99 + 886073a commit f5aa346

File tree

7 files changed

+150
-42
lines changed

7 files changed

+150
-42
lines changed

.github/CODEOWNERS

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
# These owners will be the default owners for everything in the repo
2-
* @Phinease @liutao12138
2+
* @Phinease
3+
4+
doc/docs/zh/opensource-memorial-wall.md @WMC001
5+
doc/docs/en/opensource-memorial-wall.md @WMC001

doc/docs/zh/opensource-memorial-wall.md

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
请保持消息的礼貌和尊重,符合我们的行为准则。
1717
-->
1818

19+
::: info fishcat - 2025-10-31
20+
很好的项目,希望蒸蒸日上
21+
:::
22+
1923
::: tip aibito - 某创业公司后端开发 - 2025-05-18
2024
我们是一家只有 15 人的小公司,之前一直想做智能客服但技术门槛太高。发现 Nexent 后如获至宝!20+ 文件格式支持让我们轻松处理用户上传的各种文档,多模态对话功能完美解决了语音客服需求。最重要的是,我们的产品经理现在也能直接用自然语言调整智能体逻辑,开发效率提升了好几倍!
2125
:::
@@ -24,6 +28,10 @@
2428
第一次玩开源项目,nexent真的挺好用的!用自然语言就能搞智能体,比我想象的简单多了
2529
:::
2630

31+
::: tip xingkongF001 - 2025-10-30
32+
来参加华为ICT的,希望一切顺利!!!
33+
:::
34+
2735
::: tip bytedancer2023 - 2025-05-18
2836
我们小公司想做客服机器人,之前技术门槛太高了。nexent的多文件格式支持真的帮了大忙,产品经理现在也能自己调智能体了哈哈
2937
:::
@@ -163,18 +171,45 @@ Nexent的自然语言生成Agent以及多智能体协同是我一直在研究的
163171
希望能参加ict大赛长长见识,提高水平~
164172
:::
165173

166-
::: info - 2025-10-15
167-
希望能参加ict大赛长长见识,提高水平~
174+
::: info niceman - 2025-10-27 
175+
希望能参加ict大赛可以学习到更多知识,感谢 Nexent 让我踏上了开源之旅~
176+
177+
::: info violet-dq - 2025-10-28 
178+
想要自己尝试搭建智能体,感叹Nexent的功能如此强大!
168179
:::
169180

170-
::: info - 2025-10-15
171-
希望能参加ict大赛长长见识,提高水平~
181+
::: info 龙城三少 - 2025-10-29
182+
中华有为
172183
:::
173-
参加ICT大赛来了解 Nexent,这真的是个很好的平台,未来一起前行吧
174184

175-
::: info niceman - 2025-10-27 
176-
希望能参加ict大赛可以学习到更多知识,感谢 Nexent 让我踏上了开源之旅~
185+
::: info yang 2025-11-02
186+
Nexent功能如此之强大,给我很多帮助,感谢开发者!厉害
187+
:::
177188

178-
::: info violet-dq - 2025-10-28 
189+
::: info y-dq - 2025-10-28 
179190
想要自己尝试搭建智能体,感叹Nexent的功能如此强大!
180191
:::
192+
193+
::: info zhangwt0601 - 2025-11-1
194+
希望借助开源大赛以及Nexent平台提高自己的技术
195+
:::
196+
197+
::: info - 2025-11-01
198+
来参加ict大赛培训大会,努力学习:)
199+
:::
200+
201+
::: info kisskisszhou - 2025-10-31
202+
感谢 Nexent 让我踏上了开源之旅!希望参加ict大赛来提高自己的能力
203+
:::
204+
205+
::: Pharaoh-C - 2025-11-2
206+
研究多智能体协作方向,Nexent 的多智能体协同功能让我眼前一亮,这在学术研究中太重要了。我用 Nexent 搭建了一个AI赛博医生,能够自动索引中西医文献、给一些症状做出解答。开源的力量真的很强大,希望更多研究者能加入进来!
207+
:::
208+
209+
::: info xUxIAOrUI -2025-10-28
210+
“零代码生成智能体”的概念非常吸引我.作为在校大学生,这是我第一次接触开源项目。通过初步的了解,发现Nexent是一个很好的平台,之后也会在使用的过程中尝试提出一些有用的意见。期待Nexent越来越好!
211+
:::
212+
213+
::: info niceman - 2025-10-29
214+
希望能参加ict大赛可以学习到更多知识,感谢 Nexent 让我踏上了开源之旅~
215+
:::

frontend/app/[locale]/setup/agents/components/AgentSetupOrchestrator.tsx

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,27 @@ export default function AgentSetupOrchestrator({
214214
useEffect(() => {
215215
if (isCreatingNewAgent) {
216216
if (!isEditingAgent) {
217-
// Only clear and get new Agent configuration in creating mode
217+
// Clear configuration in creating mode
218218
setBusinessLogic("");
219-
fetchSubAgentIdAndEnableToolList(t);
219+
// Create agent record immediately to get agent ID for generating prompts and using tools
220+
// Only create if we don't already have a mainAgentId
221+
if (!mainAgentId) {
222+
const createAgentRecord = async () => {
223+
try {
224+
const createResult = await getCreatingSubAgentId();
225+
if (createResult.success && createResult.data) {
226+
const newAgentId = createResult.data.agentId;
227+
setMainAgentId(newAgentId);
228+
log.info("Created agent record with ID:", newAgentId);
229+
} else {
230+
log.error("Failed to create agent record:", createResult.message);
231+
}
232+
} catch (error) {
233+
log.error("Error creating agent record:", error);
234+
}
235+
};
236+
createAgentRecord();
237+
}
220238
} else {
221239
// In edit mode, data is loaded in handleEditAgent, here validate the form
222240
}
@@ -236,7 +254,7 @@ export default function AgentSetupOrchestrator({
236254
// Sign that has been initialized
237255
hasInitialized.current = true;
238256
}
239-
}, [isCreatingNewAgent, isEditingAgent]);
257+
}, [isCreatingNewAgent, isEditingAgent, mainAgentId]);
240258

241259
// Listen for changes in the tool status, update the selected tool
242260
useEffect(() => {
@@ -355,6 +373,16 @@ export default function AgentSetupOrchestrator({
355373

356374
// Reset the status when the user cancels the creation of an Agent
357375
const handleCancelCreating = async () => {
376+
// If we created an agent record during creation mode, delete it
377+
if (mainAgentId && isCreatingNewAgent && !isEditingAgent) {
378+
try {
379+
await deleteAgent(Number(mainAgentId));
380+
log.info("Deleted unsaved agent record with ID:", mainAgentId);
381+
} catch (error) {
382+
log.error("Error deleting unsaved agent record:", error);
383+
}
384+
}
385+
358386
// First notify external editing state change to avoid UI jumping
359387
onEditingStateChange?.(false, null);
360388

@@ -368,6 +396,9 @@ export default function AgentSetupOrchestrator({
368396
}
369397
setIsEditingAgent(false);
370398
setEditingAgent(null);
399+
400+
// Clear the mainAgentId
401+
setMainAgentId(null);
371402

372403
// Note: Content clearing is handled by onExitCreation above
373404
// Delay clearing tool and collaborative agent selection to avoid jumping
@@ -424,11 +455,12 @@ export default function AgentSetupOrchestrator({
424455
max_step: number,
425456
business_description: string
426457
) => {
427-
if (name.trim() && mainAgentId) {
458+
if (name.trim()) {
428459
try {
429460
let result;
430461

431462
if (isEditingAgent && editingAgent) {
463+
// Editing existing agent
432464
result = await updateAgent(
433465
Number(editingAgent.id),
434466
name,
@@ -447,6 +479,13 @@ export default function AgentSetupOrchestrator({
447479
businessLogicModelId ?? undefined
448480
);
449481
} else {
482+
// Creating new agent - the agent record should already exist (created when entering create mode)
483+
if (!mainAgentId) {
484+
message.error(t("businessLogic.config.error.noAgentId"));
485+
return;
486+
}
487+
488+
// Update the agent with all the details
450489
result = await updateAgent(
451490
Number(mainAgentId),
452491
name,
@@ -480,6 +519,7 @@ export default function AgentSetupOrchestrator({
480519
setIsCreatingNewAgent(false);
481520
setIsEditingAgent(false);
482521
setEditingAgent(null);
522+
setMainAgentId(null); // Clear mainAgentId after successful save
483523
onEditingStateChange?.(false, null);
484524

485525
setBusinessLogic("");
@@ -690,16 +730,17 @@ export default function AgentSetupOrchestrator({
690730
const targetAgentId =
691731
isEditingAgent && editingAgent ? editingAgent.id : mainAgentId;
692732

693-
if (!targetAgentId) {
694-
message.error(t("businessLogic.config.error.noAgentId"));
695-
return;
696-
}
697-
698733
const newValue = value ?? 5;
699734

700735
// Update local state first
701736
setMainAgentMaxStep(newValue);
702737

738+
// If no agent ID yet (e.g., during initial creation setup), just update local state
739+
// The max steps will be saved when the agent is fully created
740+
if (!targetAgentId) {
741+
return;
742+
}
743+
703744
// Call updateAgent API to save the max steps change
704745
try {
705746
const result = await updateAgent(

frontend/app/[locale]/setup/agents/components/PromptManager.tsx

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -541,26 +541,32 @@ export default function PromptManager({
541541
{t("businessLogic.title")}
542542
</h3>
543543
</div>
544-
<div className="relative">
545-
<Input.TextArea
546-
value={businessLogic}
547-
onChange={(e) => onBusinessLogicChange?.(e.target.value)}
548-
placeholder={t("businessLogic.placeholder")}
549-
className="w-full resize-none p-3 text-sm transition-all duration-300 system-prompt-business-logic"
550-
style={{
551-
minHeight: "120px",
552-
maxHeight: "200px",
553-
paddingRight: "12px",
554-
paddingBottom: "40px", // Reserve space for button
555-
}}
556-
autoSize={{
557-
minRows: 3,
558-
maxRows: 5,
559-
}}
560-
disabled={!isEditingMode}
561-
/>
562-
{/* Generate button */}
563-
<div className="absolute bottom-2 right-2">
544+
545+
{/* 重新设计的容器:分为文本区域和控件区域 */}
546+
<div className="border border-gray-200 rounded-lg overflow-hidden bg-white shadow-sm" style={{ minHeight: "120px", maxHeight: "200px" }}>
547+
{/* 文本内容区域 */}
548+
<div className="px-2 pt-2 pb-1 overflow-hidden" style={{ minHeight: "80px", maxHeight: "160px" }}>
549+
<Input.TextArea
550+
value={businessLogic}
551+
onChange={(e) => onBusinessLogicChange?.(e.target.value)}
552+
placeholder={t("businessLogic.placeholder")}
553+
className="w-full resize-none text-sm transition-all duration-300"
554+
style={{
555+
minHeight: "80px",
556+
maxHeight: "160px",
557+
border: "none",
558+
boxShadow: "none",
559+
padding: 0,
560+
background: "transparent",
561+
overflow: "auto",
562+
}}
563+
autoSize={false}
564+
disabled={!isEditingMode}
565+
/>
566+
</div>
567+
568+
{/* 控件区域 - 固定40px高度,无背景无边框,控件靠右 */}
569+
<div className="h-10 flex items-center justify-end px-3">
564570
<div className="flex items-center gap-2">
565571
<span className="text-xs text-gray-600">{t("businessLogic.config.model")}</span>
566572
<Select

frontend/app/[locale]/setup/models/components/model/ModelAddDialog.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,26 @@ export const ModelAddDialog = ({
4747
const { t } = useTranslation();
4848
const { message } = App.useApp();
4949
const { updateModelConfig } = useConfig();
50+
51+
// Parse backend error message and return i18n key with params
52+
const parseModelError = (errorMessage: string): { key: string; params?: Record<string, string> } => {
53+
if (!errorMessage) {
54+
return { key: 'model.dialog.error.addFailed' }
55+
}
56+
57+
// Check for name conflict error
58+
const nameConflictMatch = errorMessage.match(/Name ['"]?([^'"]+)['"]? is already in use/i)
59+
if (nameConflictMatch) {
60+
return {
61+
key: 'model.dialog.error.nameConflict',
62+
params: { name: nameConflictMatch[1] }
63+
}
64+
}
65+
66+
// For other errors, return generic error key without showing backend details
67+
return { key: 'model.dialog.error.addFailed' }
68+
}
69+
5070
const [form, setForm] = useState({
5171
type: MODEL_TYPES.LLM as ModelType,
5272
name: "",
@@ -260,7 +280,8 @@ export const ModelAddDialog = ({
260280
onSuccess();
261281
}
262282
} catch (error: any) {
263-
message.error(error?.message || "添加模型失败");
283+
const errorInfo = parseModelError(error?.message || "")
284+
message.error(t(errorInfo.key, errorInfo.params))
264285
}
265286

266287
setForm((prev) => ({
@@ -419,7 +440,9 @@ export const ModelAddDialog = ({
419440
// Close the dialog
420441
onClose();
421442
} catch (error) {
422-
message.error(t("model.dialog.error.addFailed", { error }));
443+
const errorMessage = error instanceof Error ? error.message : String(error)
444+
const errorInfo = parseModelError(errorMessage)
445+
message.error(t(errorInfo.key, errorInfo.params));
423446
log.error(t("model.dialog.error.addFailedLog"), error);
424447
} finally {
425448
setLoading(false);

frontend/public/locales/en/common.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@
560560
"model.dialog.status.verifying": "Verifying model connectivity...",
561561
"model.dialog.success.connectivityVerified": "Model connectivity verification successful!",
562562
"model.dialog.error.connectivityRequired": "Please verify model connectivity and ensure connection is successful before adding the model",
563-
"model.dialog.error.addFailed": "Failed to add model: {{error}}",
563+
"model.dialog.error.addFailed": "Failed to add model",
564564
"model.dialog.error.addFailedLog": "Failed to add model",
565565
"model.dialog.error.noModelsFetched": "Please check your API key and network connectivity",
566566
"model.dialog.message.noModels": "Please fetch models first",

frontend/public/locales/zh/common.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@
560560
"model.dialog.warning.incompleteForm": "请先填写完整的模型配置信息",
561561
"model.dialog.status.verifying": "正在验证模型连通性...",
562562
"model.dialog.error.connectivityRequired": "请先验证模型连通性且确保连接成功后再添加模型",
563-
"model.dialog.error.addFailed": "添加模型失败:{{error}}",
563+
"model.dialog.error.addFailed": "添加模型失败",
564564
"model.dialog.error.addFailedLog": "添加模型失败",
565565
"model.dialog.error.noModelsFetched": "请检查相关API Key以及网络连通性",
566566
"model.dialog.message.noModels": "请先获取模型",

0 commit comments

Comments
 (0)