diff --git a/ui/src/ui/app-render.ts b/ui/src/ui/app-render.ts
index 9eece106d..ae6ba1328 100644
--- a/ui/src/ui/app-render.ts
+++ b/ui/src/ui/app-render.ts
@@ -391,6 +391,115 @@ export function renderApp(state: AppViewState) {
             ? renderAgents({
                 loading: state.agentsLoading,
                 error: state.agentsError,
+                showCreateForm: state.showCreateForm,
+                createMode: state.createMode,
+                createName: state.createName,
+                createWorkspace: state.createWorkspace,
+                createEmoji: state.createEmoji,
+                creating: state.creating,
+                createError: state.createError,
+                wizardDescription: state.wizardDescription,
+                wizardLoading: state.wizardLoading,
+                wizardResult: state.wizardResult,
+                onToggleCreateForm: () => {
+                  state.showCreateForm = !state.showCreateForm;
+                  state.createError = null;
+                  state.wizardResult = null;
+                },
+                onCreateModeChange: (mode: "manual" | "wizard") => {
+                  state.createMode = mode;
+                  state.createError = null;
+                },
+                onCreateNameChange: (v: string) => {
+                  state.createName = v;
+                  // Auto-generate workspace slug from name
+                  const slug = v.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
+                  state.createWorkspace = slug ? `~/.openclaw/workspaces/${slug}/` : "";
+                },
+                onCreateWorkspaceChange: (v: string) => { state.createWorkspace = v; },
+                onCreateEmojiChange: (v: string) => { state.createEmoji = v; },
+                onCreateAgent: async () => {
+                  state.creating = true;
+                  state.createError = null;
+                  try {
+                    const name = state.createName.trim();
+                    const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
+                    const workspace = state.createWorkspace.trim() || `~/.openclaw/workspaces/${slug}/`;
+                    const params: Record<string, unknown> = { name, workspace };
+                    if (state.createEmoji.trim()) params.emoji = state.createEmoji.trim();
+                    const res = await state.client?.request("agents.create", params) as { ok?: boolean; error?: string } | null;
+                    if (res?.ok) {
+                      state.showCreateForm = false;
+                      state.createName = "";
+                      state.createWorkspace = "";
+                      state.createEmoji = "";
+                      state.agentsLoading = true;
+                      const list = await state.client?.request("agents.list", {});
+                      state.agentsList = list as typeof state.agentsList;
+                      state.agentsLoading = false;
+                      // Refresh configForm so the new agent is found when selected
+                      await loadConfig(state);
+                    } else {
+                      state.createError = (res as { ok?: boolean; error?: string } | null)?.error ?? "Failed to create agent";
+                    }
+                  } catch (err) {
+                    state.createError = String(err);
+                  } finally {
+                    state.creating = false;
+                  }
+                },
+                onWizardDescriptionChange: (v: string) => { state.wizardDescription = v; },
+                onWizardGenerate: async () => {
+                  state.wizardLoading = true;
+                  state.wizardResult = null;
+                  state.createError = null;
+                  try {
+                    const res = await state.client?.request("agents.wizard", {
+                      description: state.wizardDescription,
+                    }) as { name: string; emoji: string; soul: string } | null;
+                    if (res?.name) {
+                      state.wizardResult = res;
+                    } else {
+                      state.createError = "Wizard returned empty result";
+                    }
+                  } catch (err) {
+                    state.createError = String(err);
+                  } finally {
+                    state.wizardLoading = false;
+                  }
+                },
+                onWizardAccept: async () => {
+                  if (!state.wizardResult) return;
+                  state.creating = true;
+                  state.createError = null;
+                  try {
+                    const name = state.wizardResult.name;
+                    const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
+                    const workspace = `~/.openclaw/workspaces/${slug}/`;
+                    const params: Record<string, unknown> = {
+                      name,
+                      workspace,
+                      emoji: state.wizardResult.emoji,
+                    };
+                    const res = await state.client?.request("agents.create", params) as { ok?: boolean; agentId?: string; error?: string } | null;
+                    if (res?.ok) {
+                      // Write the generated SOUL.md to the agent's workspace
+                      try {
+                        await state.client?.request("agents.files.set", {
+                          agentId: res.agentId,
+                          name: "SOUL.md",
+                          content: state.wizardResult.soul,
+                        });
+                      } catch { /* best effort */ }
+                      state.showCreateForm = false;
+                      state.wizardResult = null;
+                      state.wizardDescription = "";
+                      state.createMode = "manual";
+                      state.agentsLoading = true;
+                      const list = await state.client?.request("agents.list", {});
+                      state.agentsList = list as typeof state.agentsList;
+                      state.agentsLoading = false;
+                      // Refresh configForm so the new agent is found when selected
+                      await loadConfig(state);
+                    } else {
+                      state.createError = (res as { ok?: boolean; agentId?: string; error?: string } | null)?.error ?? "Failed to create agent";
+                    }
+                  } catch (err) {
+                    state.createError = String(err);
+                  } finally {
+                    state.creating = false;
+                  }
+                },
                 agentsList: state.agentsList,
                 selectedAgentId: resolvedAgentId,
                 activePanel: state.agentsPanel,
