diff --git a/src/commands/agents.config.ts b/src/commands/agents.config.ts
index 26c70932f..cd778740e 100644
--- a/src/commands/agents.config.ts
+++ b/src/commands/agents.config.ts
@@ -34,6 +34,7 @@ export type AgentIdentity = {
creature?: string;
vibe?: string;
theme?: string;
+ avatar?: string;
};
export function listAgentEntries(cfg: ClawdbotConfig): AgentEntry[] {
@@ -90,6 +91,7 @@ export function parseIdentityMarkdown(content: string): AgentIdentity {
if (label === "creature") identity.creature = value;
if (label === "vibe") identity.vibe = value;
if (label === "theme") identity.theme = value;
+ if (label === "avatar") identity.avatar = value;
}
return identity;
}
@@ -99,7 +101,14 @@ export function loadAgentIdentity(workspace: string): AgentIdentity | null {
try {
const content = fs.readFileSync(identityPath, "utf-8");
const parsed = parseIdentityMarkdown(content);
- if (!parsed.name && !parsed.emoji && !parsed.theme && !parsed.creature && !parsed.vibe) {
+ if (
+ !parsed.name &&
+ !parsed.emoji &&
+ !parsed.theme &&
+ !parsed.creature &&
+ !parsed.vibe &&
+ !parsed.avatar
+ ) {
return null;
}
return parsed;
diff --git a/src/config/types.base.ts b/src/config/types.base.ts
index 8d7613936..71d051e5b 100644
--- a/src/config/types.base.ts
+++ b/src/config/types.base.ts
@@ -154,4 +154,6 @@ export type IdentityConfig = {
name?: string;
theme?: string;
emoji?: string;
+ /** Path to a custom avatar image (relative to workspace or absolute). */
+ avatar?: string;
};
diff --git a/ui/src/styles/chat/grouped.css b/ui/src/styles/chat/grouped.css
index dea387c45..36a2c7e01 100644
--- a/ui/src/styles/chat/grouped.css
+++ b/ui/src/styles/chat/grouped.css
@@ -89,6 +89,12 @@
color: rgba(134, 142, 150, 1);
}
+/* Image avatar support */
+img.chat-avatar {
+ object-fit: cover;
+ object-position: center;
+}
+
/* Minimal Bubble Design - dynamic width based on content */
.chat-bubble {
position: relative;
diff --git a/ui/src/ui/chat/grouped-render.ts b/ui/src/ui/chat/grouped-render.ts
index caa4731a1..ca973ce08 100644
--- a/ui/src/ui/chat/grouped-render.ts
+++ b/ui/src/ui/chat/grouped-render.ts
@@ -105,7 +105,7 @@ export function renderMessageGroup(
`;
}
-function renderAvatar(role: string) {
+function renderAvatar(role: string, avatarUrl?: string) {
const normalized = normalizeRoleForGrouping(role);
const initial =
normalized === "user"
@@ -123,6 +123,12 @@ function renderAvatar(role: string) {
: normalized === "tool"
? "tool"
: "other";
+
+ // If avatar URL is provided for assistant, show image
+ if (avatarUrl && normalized === "assistant") {
+ return html``;
+ }
+
return html`