From eab04aaee30439bf81a6e4efc877012c65d5ae6e Mon Sep 17 00:00:00 2001 From: Shubham Naik Date: Fri, 7 Nov 2025 20:48:12 -0800 Subject: [PATCH] chore: allow renaming agent (#83) Co-authored-by: Shubham Naik --- src/cli/App.tsx | 68 ++++++++++++++++++++++++++- src/cli/commands/registry.ts | 7 +++ src/cli/components/CommandPreview.tsx | 11 ++++- src/cli/components/InputAssist.tsx | 3 ++ src/cli/components/InputRich.tsx | 3 ++ 5 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/cli/App.tsx b/src/cli/App.tsx index b75d983..e9d15eb 100644 --- a/src/cli/App.tsx +++ b/src/cli/App.tsx @@ -174,6 +174,7 @@ export default function App({ // Model selector state const [modelSelectorOpen, setModelSelectorOpen] = useState(false); const [llmConfig, setLlmConfig] = useState(null); + const [agentName, setAgentName] = useState(null); // Token streaming preference (can be toggled at runtime) const [tokenStreamingEnabled, setTokenStreamingEnabled] = @@ -397,8 +398,9 @@ export default function App({ const client = await getClient(); const agent = await client.agents.retrieve(agentId); setLlmConfig(agent.llm_config); + setAgentName(agent.name); } catch (error) { - console.error("Error fetching llm_config:", error); + console.error("Error fetching agent config:", error); } }; fetchConfig(); @@ -1014,6 +1016,69 @@ export default function App({ return { submitted: true }; } + // Special handling for /rename command - rename the agent + if (msg.trim().startsWith("/rename")) { + const parts = msg.trim().split(/\s+/); + const newName = parts.slice(1).join(" "); + + if (!newName) { + const cmdId = uid("cmd"); + buffersRef.current.byId.set(cmdId, { + kind: "command", + id: cmdId, + input: msg, + output: "Please provide a new name: /rename ", + phase: "finished", + success: false, + }); + buffersRef.current.order.push(cmdId); + refreshDerived(); + return { submitted: true }; + } + + const cmdId = uid("cmd"); + buffersRef.current.byId.set(cmdId, { + kind: "command", + id: cmdId, + input: msg, + output: `Renaming agent to "${newName}"...`, + phase: "running", + }); + buffersRef.current.order.push(cmdId); + refreshDerived(); + + setCommandRunning(true); + + try { + const client = await getClient(); + await client.agents.modify(agentId, { name: newName }); + setAgentName(newName); + + buffersRef.current.byId.set(cmdId, { + kind: "command", + id: cmdId, + input: msg, + output: `Agent renamed to "${newName}"`, + phase: "finished", + success: true, + }); + refreshDerived(); + } catch (error) { + buffersRef.current.byId.set(cmdId, { + kind: "command", + id: cmdId, + input: msg, + output: `Failed: ${error instanceof Error ? error.message : String(error)}`, + phase: "finished", + success: false, + }); + refreshDerived(); + } finally { + setCommandRunning(false); + } + return { submitted: true }; + } + // Immediately add command to transcript with "running" phase const cmdId = uid("cmd"); buffersRef.current.byId.set(cmdId, { @@ -1662,6 +1727,7 @@ export default function App({ onInterrupt={handleInterrupt} interruptRequested={interruptRequested} agentId={agentId} + agentName={agentName} /> {/* Model Selector - conditionally mounted as overlay */} diff --git a/src/cli/commands/registry.ts b/src/cli/commands/registry.ts index 5700e1f..d1f4c9c 100644 --- a/src/cli/commands/registry.ts +++ b/src/cli/commands/registry.ts @@ -64,6 +64,13 @@ export const commands: Record = { return "Removing tools..."; }, }, + "/rename": { + desc: "Rename the current agent", + handler: () => { + // Handled specially in App.tsx to access agent ID and client + return "Renaming agent..."; + }, + }, }; /** diff --git a/src/cli/components/CommandPreview.tsx b/src/cli/components/CommandPreview.tsx index 33bb86d..1e512a6 100644 --- a/src/cli/components/CommandPreview.tsx +++ b/src/cli/components/CommandPreview.tsx @@ -12,10 +12,12 @@ const commandList = Object.entries(commands).map(([cmd, { desc }]) => ({ export function CommandPreview({ currentInput, agentId, + agentName, serverUrl, }: { currentInput: string; agentId?: string; + agentName?: string | null; serverUrl?: string; }) { if (!currentInput.startsWith("/")) { @@ -40,7 +42,14 @@ export function CommandPreview({ ))} {showBottomBar && ( - + + {agentName && Agent: {agentName}} {isCloudUser ? ( View agent in ADE diff --git a/src/cli/components/InputAssist.tsx b/src/cli/components/InputAssist.tsx index 1cea234..61b9e38 100644 --- a/src/cli/components/InputAssist.tsx +++ b/src/cli/components/InputAssist.tsx @@ -7,6 +7,7 @@ interface InputAssistProps { onFileSelect: (path: string) => void; onAutocompleteActiveChange: (isActive: boolean) => void; agentId?: string; + agentName?: string | null; serverUrl?: string; } @@ -22,6 +23,7 @@ export function InputAssist({ onFileSelect, onAutocompleteActiveChange, agentId, + agentName, serverUrl, }: InputAssistProps) { // Show file autocomplete when @ is present @@ -42,6 +44,7 @@ export function InputAssist({ ); diff --git a/src/cli/components/InputRich.tsx b/src/cli/components/InputRich.tsx index 9e73e81..61352b9 100644 --- a/src/cli/components/InputRich.tsx +++ b/src/cli/components/InputRich.tsx @@ -31,6 +31,7 @@ export function Input({ onInterrupt, interruptRequested = false, agentId, + agentName, }: { visible?: boolean; streaming: boolean; @@ -44,6 +45,7 @@ export function Input({ onInterrupt?: () => void; interruptRequested?: boolean; agentId?: string; + agentName?: string | null; }) { const [value, setValue] = useState(""); const [escapePressed, setEscapePressed] = useState(false); @@ -478,6 +480,7 @@ export function Input({ onFileSelect={handleFileSelect} onAutocompleteActiveChange={setIsAutocompleteActive} agentId={agentId} + agentName={agentName} serverUrl={serverUrl} />