refuse a duplicate agent name in the panel, not in a 500
The server's uniqueness check is the one that matters, but its 409 currently never fires (the constraint name is on err.cause, not in the DrizzleQueryError message), so a collision came back as "Internal Server Error". The address book is already in hand here — checking it first turns the common case into a sentence the human can act on. Diagnosis of the server-side bug, with the patch, is in COMMS/agent-panels-split-2026-08-07.md; that file belongs to another agent and is still uncommitted, so it is theirs to apply.
This commit is contained in:
@@ -84,8 +84,14 @@ export function useAgentPanel(panelId: string) {
|
|||||||
}, [agent?.id, agent?.panelId, panelId, dashboardId, queryClient]);
|
}, [agent?.id, agent?.panelId, panelId, dashboardId, queryClient]);
|
||||||
|
|
||||||
const claim = useMutation({
|
const claim = useMutation({
|
||||||
mutationFn: (input: { name: string; cwd?: string; rolePrompt?: string }) =>
|
mutationFn: (input: { name: string; cwd?: string; rolePrompt?: string }) => {
|
||||||
clientRef.current.post<{ agent: AgentPanelView; created: boolean }>('/chat/agent-panels', {
|
// Reject a name already on this dashboard before asking the server. The uniqueness that matters is
|
||||||
|
// the server's — an address that resolved to two agents would make a handoff ambiguous — but the
|
||||||
|
// list is already in hand, and the answer here is a sentence the human can act on.
|
||||||
|
if (agents.some((a) => a.name === input.name)) {
|
||||||
|
return Promise.reject(new Error(`There is already an agent named "${input.name}" on this dashboard`));
|
||||||
|
}
|
||||||
|
return clientRef.current.post<{ agent: AgentPanelView; created: boolean }>('/chat/agent-panels', {
|
||||||
dashboardId,
|
dashboardId,
|
||||||
panelId,
|
panelId,
|
||||||
// Record the directory the panel is already scoped to. A row with no cwd runs incoming handoffs
|
// Record the directory the panel is already scoped to. A row with no cwd runs incoming handoffs
|
||||||
@@ -93,7 +99,8 @@ export function useAgentPanel(panelId: string) {
|
|||||||
// agent working in two places depending on who spoke to it.
|
// agent working in two places depending on who spoke to it.
|
||||||
...(cwd && cwd !== '~' ? { cwd } : {}),
|
...(cwd && cwd !== '~' ? { cwd } : {}),
|
||||||
...input,
|
...input,
|
||||||
}),
|
});
|
||||||
|
},
|
||||||
onSuccess: ({ agent: created }) => {
|
onSuccess: ({ agent: created }) => {
|
||||||
// Write the name into the panel before invalidating: the config is what survives a drag, and a
|
// Write the name into the panel before invalidating: the config is what survives a drag, and a
|
||||||
// refetch that landed first would show an agent this panel does not yet claim.
|
// refetch that landed first would show an agent this panel does not yet claim.
|
||||||
|
|||||||
Reference in New Issue
Block a user