Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions apps/web/src/bench/bench-pill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,7 @@ export function BenchPill({
<Skeleton className="size-6 rounded-full" />
)
) : (
<IdentityAvatar
kind="agent"
name={worker.name}
principalId={worker.id}
status={status.tone}
/>
<IdentityAvatar kind="agent" name={worker.name} principalId={worker.id} />
)}
<b>{benchName}</b>
<span className="bench-pill-status">{statusLine(status, worker?.name)}</span>
Expand Down
31 changes: 31 additions & 0 deletions apps/web/src/chat/avatar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* Workers are hue-tinted rounded squares, people are ink circles. Unlayered,
so it wins over react-ui's utility-layer tone fill. */
.wb-av--orange {
background: var(--hue-orange-bg);
color: var(--hue-ink);
}
.wb-av--blue {
background: var(--hue-blue-bg);
color: var(--hue-ink);
}
.wb-av--green {
background: var(--hue-green-bg);
color: var(--hue-ink);
}
.wb-av--person {
background: var(--ink);
color: var(--canvas);
}

/* The status dot is the only round non-initials child. */
.wb-av > span.rounded-full {
width: 8px;
height: 8px;
right: -2px;
bottom: -2px;
background: var(--success);
--tw-ring-color: var(--surface);
}
.wb-av > span.rounded-full.bg-primary-emphasis {
background: var(--action);
}
16 changes: 15 additions & 1 deletion apps/web/src/chat/avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from "@corbits/react-ui";

import { agentInitials } from "@/chat/threads-api";
import "./avatar.css";

// Token references, not hex, so no product code hardcodes a color value.
export const AVATAR_COLORS = ["--avatar-1", "--avatar-2", "--avatar-3", "--avatar-4"] as const;
Expand All @@ -32,6 +33,14 @@ export const avatarColorClass: Record<AvatarColor, string> = {
"--avatar-4": "bg-(--avatar-4) text-black",
};

const WORKER_HUES = ["orange", "blue", "green"] as const;

// Hashed off the name: each bench deploys its own copy of a worker with a new
// principal id, so the id would recolor one worker per bench.
function workerHueClass(name: string): string {
return `wb-av--${WORKER_HUES[hashPrincipal(name) % WORKER_HUES.length]}`;
}

export function hashPrincipal(principalId: string): number {
let hash = 0;
for (let index = 0; index < principalId.length; index += 1) {
Expand Down Expand Up @@ -98,7 +107,12 @@ export function WorkbenchAvatar({
shape={kind === "person" ? "circle" : "square"}
orbit={kind === "worker" && status === "working"}
{...(status === undefined ? {} : { status })}
{...(className === undefined ? {} : { className })}
className={[
kind === "person" ? "wb-av wb-av--person" : `wb-av ${workerHueClass(name)}`,
className,
]
.filter((c) => c !== undefined)
.join(" ")}
/>
);
}
Expand Down
Loading