Skip to content

Commit 5182770

Browse files
committed
🐛 Bugfix: When creating a new Agent, the user is not prompted to save it before debugging
🐛 Bugfix: Agent modification of unsaved prompts can bypass information verification 🐛 Bugfix: When an Agent is selected and another Agent is imported, it will prompt that there are modifications 🐛 Bugfix: Creating agents will inherit tool parameters wrongly from previous selected agent
1 parent ef19880 commit 5182770

File tree

5 files changed

+68
-12
lines changed

5 files changed

+68
-12
lines changed

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

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -500,15 +500,20 @@ export default function AgentSetupOrchestrator({
500500

501501
const confirmOrRun = useCallback(
502502
(action: PendingAction) => {
503-
if (hasUnsavedChanges) {
503+
// In creation mode, always show save confirmation dialog when clicking debug
504+
if (isCreatingNewAgent && !isEditingAgent) {
505+
setPendingAction(() => action);
506+
setConfirmContext("switch");
507+
setIsSaveConfirmOpen(true);
508+
} else if (hasUnsavedChanges) {
504509
setPendingAction(() => action);
505510
setConfirmContext("switch");
506511
setIsSaveConfirmOpen(true);
507512
} else {
508513
void Promise.resolve(action());
509514
}
510515
},
511-
[hasUnsavedChanges]
516+
[hasUnsavedChanges, isCreatingNewAgent, isEditingAgent]
512517
);
513518

514519
const handleToolConfigDraftSave = useCallback(
@@ -905,6 +910,8 @@ export default function AgentSetupOrchestrator({
905910
setSelectedTools([]);
906911
setEnabledToolIds([]);
907912
setEnabledAgentIds([]);
913+
setToolConfigDrafts({});
914+
setMainAgentId?.(null);
908915

909916
// Clear business logic model to allow default from global settings
910917
// The useEffect in PromptManager will set it to the default from localStorage
@@ -916,6 +923,12 @@ export default function AgentSetupOrchestrator({
916923
setMainAgentModel(null);
917924
setMainAgentModelId(null);
918925

926+
try {
927+
await onToolsRefresh?.(false);
928+
} catch (error) {
929+
log.error("Failed to refresh tools in creation mode:", error);
930+
}
931+
919932
onEditingStateChange?.(false, null);
920933
};
921934

@@ -1545,7 +1558,8 @@ export default function AgentSetupOrchestrator({
15451558
message.success(
15461559
translationFn("businessLogic.config.error.agentImportSuccess")
15471560
);
1548-
await refreshAgentList(translationFn);
1561+
// Don't clear tools when importing to avoid triggering false unsaved changes indicator
1562+
await refreshAgentList(translationFn, false);
15491563
return true;
15501564
}
15511565

@@ -1745,9 +1759,26 @@ export default function AgentSetupOrchestrator({
17451759
skipUnsavedCheckRef.current = false;
17461760
}, 0);
17471761
onEditingStateChange?.(false, null);
1762+
} else {
1763+
// If deleting another agent that is in enabledAgentIds, remove it and update baseline
1764+
// to avoid triggering false unsaved changes indicator
1765+
const deletedId = Number(agentToDelete.id);
1766+
if (enabledAgentIds.includes(deletedId)) {
1767+
const updatedEnabledAgentIds = enabledAgentIds.filter(
1768+
(id) => id !== deletedId
1769+
);
1770+
setEnabledAgentIds(updatedEnabledAgentIds);
1771+
// Update baseline to reflect this change so it doesn't trigger unsaved changes
1772+
if (baselineRef.current) {
1773+
baselineRef.current = {
1774+
...baselineRef.current,
1775+
enabledAgentIds: updatedEnabledAgentIds.sort((a, b) => a - b),
1776+
};
1777+
}
1778+
}
17481779
}
1749-
// Refresh agent list
1750-
refreshAgentList(t);
1780+
// Refresh agent list without clearing tools to avoid triggering false unsaved changes indicator
1781+
refreshAgentList(t, false);
17511782
} else {
17521783
message.error(
17531784
result.message || t("businessLogic.config.error.agentDeleteFailed")
@@ -2144,6 +2175,10 @@ export default function AgentSetupOrchestrator({
21442175
// Only close modal, don't execute discard logic
21452176
setIsSaveConfirmOpen(false);
21462177
}}
2178+
canSave={localCanSaveAgent}
2179+
invalidReason={
2180+
localCanSaveAgent ? undefined : getLocalButtonTitle() || undefined
2181+
}
21472182
/>
21482183
{/* Duplicate import confirmation */}
21492184
<Modal

frontend/app/[locale]/agents/components/SaveConfirmModal.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ interface SaveConfirmModalProps {
1212
onSave: AsyncOrSyncHandler;
1313
onClose?: AsyncOrSyncHandler;
1414
width?: number;
15+
canSave?: boolean;
16+
invalidReason?: string;
1517
}
1618

1719
export default function SaveConfirmModal({
@@ -20,6 +22,8 @@ export default function SaveConfirmModal({
2022
onSave,
2123
onClose,
2224
width = 520,
25+
canSave = true,
26+
invalidReason,
2327
}: SaveConfirmModalProps) {
2428
const { t } = useTranslation("common");
2529

@@ -46,10 +50,14 @@ export default function SaveConfirmModal({
4650
centered
4751
footer={
4852
<div className="flex justify-end mt-4 gap-3">
49-
<Button onClick={handleCancel}>{t("agentConfig.modals.saveConfirm.discard")}</Button>
50-
<Button type="primary" onClick={handleSave}>
51-
{t("agentConfig.modals.saveConfirm.save")}
53+
<Button onClick={handleCancel}>
54+
{t("agentConfig.modals.saveConfirm.discard")}
5255
</Button>
56+
{canSave ? (
57+
<Button type="primary" onClick={handleSave}>
58+
{t("agentConfig.modals.saveConfirm.save")}
59+
</Button>
60+
) : null}
5361
</div>
5462
}
5563
width={width}
@@ -61,9 +69,19 @@ export default function SaveConfirmModal({
6169
style={{ fontSize: "48px" }}
6270
/>
6371
<div className="ml-3 mt-2">
64-
<div className="text-sm leading-6">
65-
{t("agentConfig.modals.saveConfirm.content")}
66-
</div>
72+
{canSave ? (
73+
<div className="text-sm leading-6">
74+
{t("agentConfig.modals.saveConfirm.content")}
75+
</div>
76+
) : (
77+
<div className="text-sm leading-6 flex flex-col gap-2">
78+
<span>
79+
{t("agentConfig.modals.saveConfirm.invalidContent", {
80+
invalidReason,
81+
})}
82+
</span>
83+
</div>
84+
)}
6785
</div>
6886
</div>
6987
</div>

frontend/app/[locale]/agents/components/tool/ToolConfigModal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,15 @@ export default function ToolConfigModal({
8484
return;
8585
}
8686

87-
// In creation mode we do not have an agent ID yet, so use the tool's default params.
87+
// In creation mode (no agent ID), always use backend-provided default params
8888
if (!normalizedAgentId) {
8989
setCurrentParams(buildDefaultParams());
9090
return;
9191
}
9292

9393
setIsLoading(true);
9494
try {
95+
// In edit mode, load tool config for the specific agent
9596
const result = await searchToolConfig(
9697
parseInt(tool.id),
9798
normalizedAgentId

frontend/public/locales/en/common.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,7 @@
904904
"agentConfig.agents.listFetchFailedDebug": "Failed to fetch Agent list:",
905905
"agentConfig.modals.saveConfirm.title": "Unsaved changes",
906906
"agentConfig.modals.saveConfirm.content": "You have unsaved changes. Would you like to save them now?",
907+
"agentConfig.modals.saveConfirm.invalidContent": "Current configuration cannot be saved: {{invalidReason}}. Please modify and try again.",
907908
"agentConfig.modals.saveConfirm.discard": "Discard",
908909
"agentConfig.modals.saveConfirm.save": "Save",
909910

frontend/public/locales/zh/common.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,7 @@
904904
"agentConfig.agents.listFetchFailedDebug": "获取 Agent 列表失败:",
905905
"agentConfig.modals.saveConfirm.title": "未保存的更改",
906906
"agentConfig.modals.saveConfirm.content": "当前Agent有未保存的更改。是否现在保存?",
907+
"agentConfig.modals.saveConfirm.invalidContent": "当前配置无法保存:{{invalidReason}}。请修改后重试。",
907908
"agentConfig.modals.saveConfirm.discard": "放弃更改",
908909
"agentConfig.modals.saveConfirm.save": "保存",
909910

0 commit comments

Comments
 (0)