feat: add agent avatar support (#1329) (thanks @dlauer)

This commit is contained in:
Peter Steinberger
2026-01-22 03:54:31 +00:00
parent 7edc464b82
commit a2bea8e366
25 changed files with 547 additions and 84 deletions

View File

@@ -54,7 +54,13 @@ describe("agents set-identity command", () => {
await fs.mkdir(workspace, { recursive: true });
await fs.writeFile(
path.join(workspace, "IDENTITY.md"),
["- Name: Clawd", "- Creature: helpful sloth", "- Emoji: :)", ""].join("\n"),
[
"- Name: Clawd",
"- Creature: helpful sloth",
"- Emoji: :)",
"- Avatar: avatars/clawd.png",
"",
].join("\n"),
"utf-8",
);
@@ -81,6 +87,7 @@ describe("agents set-identity command", () => {
name: "Clawd",
theme: "helpful sloth",
emoji: ":)",
avatar: "avatars/clawd.png",
});
});
@@ -115,7 +122,13 @@ describe("agents set-identity command", () => {
await fs.mkdir(workspace, { recursive: true });
await fs.writeFile(
path.join(workspace, "IDENTITY.md"),
["- Name: Clawd", "- Theme: space lobster", "- Emoji: :)", ""].join("\n"),
[
"- Name: Clawd",
"- Theme: space lobster",
"- Emoji: :)",
"- Avatar: avatars/base.png",
"",
].join("\n"),
"utf-8",
);
@@ -125,7 +138,7 @@ describe("agents set-identity command", () => {
});
await agentsSetIdentityCommand(
{ workspace, fromIdentity: true, name: "Nova", emoji: "🦞" },
{ workspace, fromIdentity: true, name: "Nova", emoji: "🦞", avatar: "avatars/custom.png" },
runtime,
);
@@ -137,6 +150,7 @@ describe("agents set-identity command", () => {
name: "Nova",
theme: "space lobster",
emoji: "🦞",
avatar: "avatars/custom.png",
});
});
@@ -147,9 +161,13 @@ describe("agents set-identity command", () => {
await fs.mkdir(workspace, { recursive: true });
await fs.writeFile(
identityPath,
["- **Name:** C-3PO", "- **Creature:** Flustered Protocol Droid", "- **Emoji:** 🤖", ""].join(
"\n",
),
[
"- **Name:** C-3PO",
"- **Creature:** Flustered Protocol Droid",
"- **Emoji:** 🤖",
"- **Avatar:** avatars/c3po.png",
"",
].join("\n"),
"utf-8",
);
@@ -168,6 +186,33 @@ describe("agents set-identity command", () => {
name: "C-3PO",
theme: "Flustered Protocol Droid",
emoji: "🤖",
avatar: "avatars/c3po.png",
});
});
it("accepts avatar-only identity from IDENTITY.md", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-identity-"));
const workspace = path.join(root, "work");
await fs.mkdir(workspace, { recursive: true });
await fs.writeFile(
path.join(workspace, "IDENTITY.md"),
"- Avatar: avatars/only.png\n",
"utf-8",
);
configMocks.readConfigFileSnapshot.mockResolvedValue({
...baseSnapshot,
config: { agents: { list: [{ id: "main", workspace }] } },
});
await agentsSetIdentityCommand({ workspace, fromIdentity: true }, runtime);
const written = configMocks.writeConfigFile.mock.calls[0]?.[0] as {
agents?: { list?: Array<{ id: string; identity?: Record<string, string> }> };
};
const main = written.agents?.list?.find((entry) => entry.id === "main");
expect(main?.identity).toEqual({
avatar: "avatars/only.png",
});
});