Design
llms.txt

Agents

AgentAvatar

A Digital Worker's face as a muted, looping video in a rounded square, framed and glowing in the agent's brand colour, with an optional live dot.

Crew OSAgentsMarkdown
Open

Usage#

Use it for worker cards and headers in the Crew OS control centre (Ongoing missions), next to the worker's name and role.

What you provide: videoUrl (required; the agent loop, e.g. AGENT_MEDIA[agent].url), color (required; a hex such as var(--dc-camille) resolved to #ec4899), name (for aria-label="<name> avatar"), size (sm, md default, lg), isActive (default false).

Anatomy: sm 48px with a 2px frame, md 64px / 2px, lg 96px / 3px, all rounded-xl, object-cover. Behind it a blur-lg copy of the colour at 20% opacity (30% in dark mode). The live dot sits at the bottom-right corner, 4px outside: bg-green-500, 12 / 16 / 24px by size, a 2px border-card ring and a animate-ping halo at 75%.

Behaviour: the video autoplays muted, looped and inline (play() is retried on mount). There is no fallback: with an empty videoUrl or a video that fails to load you get the empty coloured frame, as Claire shows in the second row (her loop is not in this system yet). The ping halo does not check reduced motion.

Don't pass a CSS variable string as color (it is concatenated into the glow), use it for people who are not Digital Workers (use Avatar), or show the live dot for workers that are idle.

Facts#

ProductCrew OS
FamilyAgents
Globalwindow.DigitalCrew.AgentAvatar
Sourcedigitalcrew-orchestrator: components/dc/index.ts
Import in the appimport { AgentAvatar } from "@/components/dc";

API#

TypeScript declarations emitted from components/dc/index.ts.

interface AgentAvatarProps {
    videoUrl: string;
    color: string;
    name: string;
    isActive?: boolean;
    size?: "sm" | "md" | "lg";
}
export declare function AgentAvatar({ videoUrl, color, name, isActive, size }: AgentAvatarProps): any;

Code#

The preview above, as plain React.createElement against window.DigitalCrew with realistic data. Copy it into a page that loads the bundle.

<div id="root" class="p-6"></div>
<script>
(function () {
  var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
  function tok(name) { return getComputedStyle(document.documentElement).getPropertyValue("--dc-" + name).trim(); }
  var V = { camille: "/sophie.mp4", sophie: "/design/assets/Agents/videos/sophie.mp4", max: "/design/assets/Agents/videos/max.mp4", kate: "/design/assets/Agents/videos/kate.mp4", andre: "/design/assets/Agents/videos/andre.mp4", claire: "/design/assets/Agents/videos/claire.mp4" };
  function Cell(p) {
    return h("div", { className: "grid justify-items-center gap-2" },
      h(DC.AgentAvatar, { videoUrl: p.url, color: tok(p.agent), name: p.name, size: p.size, isActive: !!p.active }),
      h("div", { className: "text-center" }, h("p", { className: "text-sm font-medium" }, p.name), h("p", { className: "text-muted-foreground text-xs" }, p.note)));
  }
  function App() {
    return h("div", { className: "grid gap-8" },
      h("div", { className: "flex items-end gap-8" },
        h(Cell, { agent: "camille", url: V.camille, name: "Camille", note: "sm", size: "sm" }),
        h(Cell, { agent: "camille", url: V.camille, name: "Camille", note: "md", size: "md" }),
        h(Cell, { agent: "camille", url: V.camille, name: "Camille", note: "lg · active", size: "lg", active: true })),
      h("div", { className: "flex items-end gap-8" },
        h(Cell, { agent: "sophie", url: V.sophie, name: "Sophie", note: "md", size: "md" }),
        h(Cell, { agent: "max", url: V.max, name: "Max", note: "md · active", size: "md", active: true }),
        h(Cell, { agent: "kate", url: V.kate, name: "Kate", note: "md", size: "md" }),
        h(Cell, { agent: "andre", url: V.andre, name: "André", note: "md", size: "md" }),
        h(Cell, { agent: "claire", url: V.claire, name: "Claire", note: "md", size: "md" }),
        h(Cell, { agent: "boss", url: "", name: "Boss", note: "no video yet", size: "md" })));
  }
  ReactDOM.createRoot(document.getElementById("root")).render(h(DC.TooltipProvider, { delayDuration: 80 }, h(App)));
})();
</script>