diff --git a/apps/web/src/bench/bench-pill.tsx b/apps/web/src/bench/bench-pill.tsx
index fe309c7aa..def8001f0 100644
--- a/apps/web/src/bench/bench-pill.tsx
+++ b/apps/web/src/bench/bench-pill.tsx
@@ -42,12 +42,7 @@ export function BenchPill({
)
) : (
-
+
)}
{benchName}
{statusLine(status, worker?.name)}
diff --git a/apps/web/src/chat/avatar.css b/apps/web/src/chat/avatar.css
new file mode 100644
index 000000000..fc992bd59
--- /dev/null
+++ b/apps/web/src/chat/avatar.css
@@ -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);
+}
diff --git a/apps/web/src/chat/avatar.tsx b/apps/web/src/chat/avatar.tsx
index 83a78bfde..637ef7978 100644
--- a/apps/web/src/chat/avatar.tsx
+++ b/apps/web/src/chat/avatar.tsx
@@ -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;
@@ -32,6 +33,14 @@ export const avatarColorClass: Record = {
"--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) {
@@ -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(" ")}
/>
);
}