> ## Documentation Index
> Fetch the complete documentation index at: https://docs.labelbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Documentation

> Docs for Recursion managed AI agents, plus Horizon and the Labelbox Python SDK.

export const HubFooter = ({links = []}) => <footer className="hub-foot">
    <div className="hub-wrap hub-foot__row">
      <span className="hub-foot__brand">
        {HubIcon({
  name: "recursion",
  size: 16
})}
        Recursion
      </span>
      <nav className="hub-foot__links" aria-label="Resources">
        {links.map(link => <a key={link.label} href={link.href}>
            {link.label}
          </a>)}
      </nav>
    </div>
  </footer>;

export const PlatformBand = ({title, description, primary, secondary, links = []}) => <section className="hub-section">
    <div className="hub-wrap">
      <div className="hub-band">
        <div className="hub-band__copy">
          <h2 className="hub-h2">{title}</h2>
          <p className="hub-section__desc">{description}</p>
          <div className="hub-ctas">
            {primary ? <a className="hub-btn hub-btn--primary" href={primary.href}>
                {primary.label}
                {HubIcon({
  name: "arrow-right",
  size: 15
})}
              </a> : null}
            {secondary ? <a className="hub-btn hub-btn--ghost" href={secondary.href}>
                {secondary.label}
                {HubIcon({
  name: "arrow-up-right",
  size: 14
})}
              </a> : null}
          </div>
        </div>
        <div className="hub-band__links">
          {links.map(link => <a key={link.title} className="hub-band__link" href={link.href}>
              <span className="hub-band__title">
                {link.title}
                {HubIcon({
  name: link.external ? "arrow-up-right" : "arrow-right",
  size: 13
})}
              </span>
              <span className="hub-band__text">{link.text}</span>
            </a>)}
        </div>
      </div>
    </div>
  </section>;

export const CapabilityGrid = ({items = []}) => <div className="hub-caps">
    {items.map(item => <a key={item.title} className="hub-cap" href={item.href}>
        <span className="hub-cap__icon">{HubIcon({
  name: item.icon,
  size: 16
})}</span>
        <span className="hub-cap__body">
          <span className="hub-cap__title">{item.title}</span>
          <span className="hub-cap__text">{item.text}</span>
        </span>
      </a>)}
  </div>;

export const PathCard = ({title, description, href, icon, cta = "Open"}) => <a className="hub-path" href={href}>
    <span className="hub-path__icon">{HubIcon({
  name: icon,
  size: 18
})}</span>
    <span className="hub-path__title">{title}</span>
    <span className="hub-path__desc">{description}</span>
    <span className="hub-path__cta">
      {cta}
      {HubIcon({
  name: "arrow-right",
  size: 14
})}
    </span>
  </a>;

export const HubSection = ({title, description, children}) => <section className="hub-section">
    <div className="hub-wrap">
      {title ? <header className="hub-section__head">
          <h2 className="hub-h2">{title}</h2>
          {description ? <p className="hub-section__desc">{description}</p> : null}
        </header> : null}
      {children}
    </div>
  </section>;

export const HubHero = ({title, accent, description, primary, secondary, setup, children}) => <section className="hub-hero">
    <div className="hub-wrap hub-hero__grid">
      <div className="hub-hero__copy">
        <h1 className="hub-display">
          {title}
          {accent ? <span className="hub-display__accent">{accent}</span> : null}
        </h1>
        <p className="hub-lede">{description}</p>
        <div className="hub-ctas">
          {primary ? <a className="hub-btn hub-btn--primary" href={primary.href}>
              {primary.label}
              {HubIcon({
  name: "arrow-right",
  size: 15
})}
            </a> : null}
          {secondary ? <a className="hub-btn hub-btn--ghost" href={secondary.href}>
              {secondary.label}
            </a> : null}
        </div>
        {setup ? <div className="hub-hero__setup">{setup}</div> : null}
      </div>
      {children ? <div className="hub-hero__stage">{children}</div> : null}
    </div>
  </section>;

export const SessionConsole = () => {
  const CYCLE = 22000;
  const RUN = 0.8;
  const START_S = 12 * 3600 + 4 * 60 + 10;
  const TOTAL_S = 167;
  const SIZES = {
    full: {
      w: 1200,
      h: 680
    },
    medium: {
      w: 1000,
      h: 680
    },
    compact: {
      w: 720,
      h: 620
    }
  };
  const [t, setT] = useState(CYCLE * 0.95);
  const [node, setNode] = useState(null);
  const [fit, setFit] = useState({
    layout: "full",
    scale: 1
  });
  useEffect(() => {
    if (!node) return undefined;
    const measure = () => {
      const width = node.clientWidth;
      const layout = width < 760 ? "compact" : width < 940 ? "medium" : "full";
      setFit({
        layout,
        scale: width / SIZES[layout].w
      });
    };
    measure();
    const observer = new ResizeObserver(measure);
    observer.observe(node);
    return () => observer.disconnect();
  }, [node]);
  useEffect(() => {
    if (!node || window.matchMedia("(prefers-reduced-motion: reduce)").matches) return undefined;
    let frame = 0;
    let base = null;
    let last = 0;
    let offset = 0;
    let running = false;
    let inView = true;
    let visible = !document.hidden;
    const tick = now => {
      if (base === null) base = now - offset;
      if (now - last > 32) {
        last = now;
        offset = (now - base) % CYCLE;
        setT(offset);
      }
      frame = requestAnimationFrame(tick);
    };
    const sync = () => {
      const active = inView && visible;
      if (active && !running) {
        running = true;
        base = null;
        frame = requestAnimationFrame(tick);
      } else if (!active && running) {
        running = false;
        cancelAnimationFrame(frame);
      }
    };
    const onVisibility = () => {
      visible = !document.hidden;
      sync();
    };
    const io = new IntersectionObserver(([entry]) => {
      inView = entry.isIntersecting;
      sync();
    }, {
      threshold: 0.05
    });
    io.observe(node);
    document.addEventListener("visibilitychange", onVisibility);
    offset = CYCLE * RUN * 0.12;
    setT(offset);
    sync();
    return () => {
      cancelAnimationFrame(frame);
      io.disconnect();
      document.removeEventListener("visibilitychange", onVisibility);
    };
  }, [node]);
  const p = Math.min(1, t / (CYCLE * RUN));
  const done = p >= 0.94;
  const fade = t > CYCLE - 400 ? (CYCLE - t) / 400 : 1;
  const pad = n => String(Math.floor(n)).padStart(2, "0");
  const clock = s => {
    const h = Math.floor(s / 3600);
    return `${(h + 11) % 12 + 1}:${pad(s % 3600 / 60)}:${pad(s % 60)} ${h >= 12 ? "PM" : "AM"}`;
  };
  const duration = s => s < 60 ? `${Math.floor(s)}s` : `${Math.floor(s / 60)}m ${pad(s % 60)}s`;
  const compactNumber = n => n >= 1000 ? `${(n / 1000).toFixed(1)}k` : `${Math.round(n)}`;
  const pct = v => `${(v * 100).toFixed(3)}%`;
  const lanes = [{
    label: "Primary agent",
    hue: "violet",
    from: 0,
    to: 0.94,
    marks: [[0, "sky"], [0.03, "slate"], [0.07, "violet", 0.035], [0.12, "teal"], [0.16, "violet", 0.05], [0.23, "violet"], [0.31, "slate"], [0.37, "violet"], [0.4, "terracotta"], [0.44, "teal"], [0.47, "slate"], [0.64, "violet", 0.04], [0.71, "slate"], [0.73, "teal"], [0.92, "slate"]]
  }, {
    label: "Grader pass 0",
    hue: "sky",
    from: 0.5,
    to: 0.6,
    marks: [[0.51, "violet"], [0.53, "violet", 0.025], [0.57, "violet"], [0.595, "crimson"]]
  }, {
    label: "Grader pass 1",
    hue: "teal",
    from: 0.76,
    to: 0.9,
    marks: [[0.77, "violet"], [0.79, "violet", 0.035], [0.85, "violet"], [0.895, "green"]]
  }];
  const rows = [{
    at: 0,
    kind: "user",
    text: "Review the repository and save the release risks as risks.md."
  }, {
    at: 0.03,
    kind: "status",
    text: "Running · the agent loop is executing",
    hue: "slate"
  }, {
    at: 0.07,
    kind: "tool",
    name: "run_command",
    arg: '{"command":"git log --oneline v2.3.0..HEAD"}',
    ms: "412ms"
  }, {
    at: 0.12,
    kind: "message",
    text: "142 commits since v2.3.0. I'll start with the schema and billing changes."
  }, {
    at: 0.16,
    kind: "tool",
    name: "run_command",
    arg: '{"command":"git diff --stat v2.3.0..HEAD -- migrations billing"}',
    ms: "1.2s"
  }, {
    at: 0.23,
    kind: "tool",
    name: "read_file",
    arg: '{"path":"migrations/0042_split_ledger.sql"}',
    ms: "38ms"
  }, {
    at: 0.31,
    kind: "checkpoint"
  }, {
    at: 0.37,
    kind: "tool",
    name: "write_artifact",
    arg: '{"path":"risks.md","content":"# Release risks\\n\\n1. Ledger split migration locks…',
    ms: "22ms"
  }, {
    at: 0.44,
    kind: "message",
    text: "Saved four release risks to risks.md, ordered by blast radius."
  }, {
    at: 0.47,
    kind: "status",
    text: "Idle · turn ended",
    hue: "slate"
  }, {
    at: 0.57,
    kind: "tool",
    thread: {
      label: "Grader pass 0",
      hue: "sky"
    },
    name: "submit_evaluation",
    arg: '{"criteria":[{"criterion_id":"c2","verdict":"fail","rationale":"Risk 3 has no owner"}',
    ms: "61ms"
  }, {
    at: 0.6,
    kind: "status",
    text: "Iteration 1 · Needs revision · Risk 3 has no owner",
    hue: "amber"
  }, {
    at: 0.64,
    kind: "tool",
    name: "write_artifact",
    arg: '{"path":"risks.md","content":"# Release risks\\n\\n1. Ledger split migration locks… Owner: @billing-oncall',
    ms: "19ms"
  }, {
    at: 0.71,
    kind: "checkpoint"
  }, {
    at: 0.73,
    kind: "message",
    text: "Every risk now names an owner and a mitigation."
  }, {
    at: 0.85,
    kind: "tool",
    thread: {
      label: "Grader pass 1",
      hue: "teal"
    },
    name: "submit_evaluation",
    arg: '{"criteria":[{"criterion_id":"c1","verdict":"pass"},{"criterion_id":"c2","verdict":"pass"}',
    ms: "49ms"
  }, {
    at: 0.92,
    kind: "status",
    text: "Idle · turn ended",
    hue: "slate"
  }, {
    at: 0.94,
    kind: "status",
    text: "Completed · outcome satisfied",
    hue: "green"
  }];
  const outcome = p >= 0.9 ? {
    label: "Satisfied",
    hue: "green"
  } : p >= 0.76 ? {
    label: "Evaluating",
    hue: "sky",
    live: true
  } : p >= 0.6 ? {
    label: "Needs revision",
    hue: "amber"
  } : p >= 0.5 ? {
    label: "Evaluating",
    hue: "sky",
    live: true
  } : {
    label: "Pending",
    hue: "slate"
  };
  const nav = [{
    label: "Agents",
    icon: "cpu"
  }, {
    label: "Skills",
    icon: "file"
  }, {
    label: "Sessions",
    icon: "message",
    active: true
  }, {
    label: "Memory",
    icon: "lightbulb"
  }, {
    label: "Files",
    icon: "file"
  }, {
    label: "Environments",
    icon: "box"
  }, {
    label: "Automations",
    icon: "repeat"
  }, {
    label: "Credential vaults",
    icon: "key"
  }, {
    label: "Integrations",
    icon: "plug"
  }, {
    label: "API keys",
    icon: "shield"
  }, {
    label: "Billing",
    icon: "card"
  }];
  const cost = [0, 0.002, 0.004, 0.009, 0.013, 0.018, 0.02, 0.026, 0.031, 0.033, 0.04, 0.046, 0.051, 0.057, 0.06];
  const spark = cost.map((c, i) => `${i / (cost.length - 1) * 240},${40 - c / 0.06 * 34}`).join(" L ");
  const elapsed = TOTAL_S * p;
  const stage = SIZES[fit.layout];
  const visibleRows = rows.filter(r => r.at <= p);
  const hueClass = hue => `hue-${hue}`;
  const cx = (...names) => names.filter(Boolean).join(" ");
  return <div className="hub-console" ref={setNode} style={{
    height: stage.h * fit.scale
  }} role="img" aria-label="Recursion console session detail: a release risk review session runs, the grader asks for one revision, and the second grading pass is satisfied.">
      <div className={cx("hc-stage", fit.layout === "medium" && "is-medium", fit.layout === "compact" && "is-compact")} style={{
    width: stage.w,
    height: stage.h,
    transform: `scale(${fit.scale})`,
    opacity: fade
  }}>
        <aside className="hc-nav">
          <div className="hc-brand">
            <span className="hc-brand__mark">{HubIcon({
    name: "recursion",
    size: 20
  })}</span>
            <span className="hc-brand__text">
              <b>Managed Agents</b>
            </span>
            {HubIcon({
    name: "panel-left",
    size: 14
  })}
          </div>
          <div className="hc-nav__list">
            {nav.map(item => <div key={item.label} className={cx("hc-nav__item", item.sub && "is-sub", item.active && "is-active")}>
                {HubIcon({
    name: item.icon,
    size: 16
  })}
                <span>{item.label}</span>
                {item.open ? HubIcon({
    name: "chevron-down",
    size: 14
  }) : null}
                {item.closed ? HubIcon({
    name: "chevron-right",
    size: 14
  }) : null}
              </div>)}
          </div>
          <div className="hc-nav__foot">
            <div className="hc-nav__item">
              {HubIcon({
    name: "users",
    size: 16
  })}
              <span>ada@example.com</span>
            </div>
          </div>
        </aside>

        <div className="hc-main">
          <header className="hc-header">
            <span className="hc-sqbtn">{HubIcon({
    name: "chevron-left",
    size: 14
  })}</span>
            <span className="hc-title">Release risk review</span>
            <span className={cx("hc-state", hueClass(done ? "green" : "sky"))}>
              <i className={cx("hc-dot", !done && "is-live")} />
              {done ? "Completed" : "Running"}
            </span>
            <span className="hc-id">b7e1c9a4-3d62-4f15-8a07-5c2e9f6d1b38</span>
            <span className="hc-sqbtn hc-sqbtn--sm">{HubIcon({
    name: "copy",
    size: 11
  })}</span>
            <div className="hc-metrics">
              <span className="hc-metric hc-metric--model">
                <small>Model</small>
                <b>anthropic/claude-haiku-4-5</b>
              </span>
              <span className="hc-metric">
                <small>Tokens</small>
                <b>{compactNumber(37200 * p)}</b>
              </span>
              <span className="hc-metric">
                <small>Elapsed</small>
                <b>{duration(elapsed)}</b>
              </span>
            </div>
            <span className="hc-more">{HubIcon({
    name: "more",
    size: 14
  })}</span>
            <span className="hc-btn">Model cost</span>
            <span className="hc-sqbtn hc-sqbtn--on">{HubIcon({
    name: "panel",
    size: 14
  })}</span>
          </header>

          <div className="hc-toolbar">
            <span className="hc-find">
              {HubIcon({
    name: "search",
    size: 12
  })}
              Find in transcript… /
            </span>
            <span className="hc-spacer" />
            <span className="hc-select">
              {HubIcon({
    name: "filter",
    size: 11
  })}
              All events
              {HubIcon({
    name: "chevron-down",
    size: 11
  })}
            </span>
            <span className="hc-zoom">
              <i>−</i>1.00×<i>+</i>
            </span>
            <span className="hc-sqbtn">{HubIcon({
    name: "updown",
    size: 12
  })}</span>
            <span className="hc-sqbtn">{HubIcon({
    name: "copy",
    size: 12
  })}</span>
            <span className="hc-sqbtn">{HubIcon({
    name: "download",
    size: 12
  })}</span>
          </div>

          <div className="hc-card hc-strip">
            {lanes.map(lane => {
    const started = p >= lane.from;
    const end = Math.min(p, lane.to);
    return <div key={lane.label} className={cx("hc-lane", hueClass(lane.hue))}>
                  {lane.marks.filter(([at]) => at <= p).map(([at, hue, span], i) => <span key={i} className={cx("hc-mark", hueClass(hue), span && "is-span")} style={{
      left: pct(at),
      width: span ? pct(Math.min(span, p - at)) : undefined
    }} />)}
                  {started && p >= lane.to ? <span className="hc-lane__end" style={{
      left: pct(end)
    }} /> : null}
                  <span className={cx("hc-lane__pill", !started && "is-idle")} style={{
      left: pct(lane.from)
    }}>
                    {lane.label}
                  </span>
                </div>;
  })}
            {!done ? <span className="hc-playhead" style={{
    left: `calc(14px + (100% - 28px) * ${p})`
  }}>
                <span className="hc-playhead__time">{clock(START_S + elapsed)}</span>
              </span> : null}
          </div>

          <div className="hc-body">
            <div className="hc-left">
              <div className="hc-card hc-outcome">
                <b>Outcome</b>
                <span className={cx("hc-state", hueClass(outcome.hue))}>
                  <i className={cx("hc-dot", outcome.live && "is-live")} />
                  {outcome.label}
                </span>
                <span className="hc-objective">Every release risk names an owner and a mitigation.</span>
                <span className="hc-details">Details</span>
              </div>

              <section className="hc-card hc-transcript">
                <div className="hc-feed">
                  {visibleRows.map((row, i) => {
    if (row.kind === "tool") {
      return <div key={i} className="hc-row hc-tool">
                          {HubIcon({
        name: "chevron-right",
        size: 12
      })}
                          {row.thread ? <span className={cx("hc-thread", hueClass(row.thread.hue))}>{row.thread.label}</span> : null}
                          {HubIcon({
        name: "asterisk",
        size: 12
      })}
                          <b>{row.name}</b>
                          <span className="hc-arg">{row.arg}</span>
                          <span className="hc-ms">{row.ms}</span>
                        </div>;
    }
    if (row.kind === "checkpoint") {
      return <div key={i} className="hc-row hc-tool">
                          {HubIcon({
        name: "chevron-right",
        size: 12
      })}
                          <span className="hc-chip">Checkpoint</span>
                        </div>;
    }
    if (row.kind === "status") {
      return <div key={i} className={cx("hc-row", "hc-statusline", hueClass(row.hue))}>
                          <i className="hc-dot" />
                          {row.text}
                        </div>;
    }
    return <div key={i} className={cx("hc-row", "hc-msg", row.kind === "user" && "is-user")}>
                        {row.kind === "user" ? <small>User</small> : null}
                        <span>{row.text}</span>
                        {row.kind === "user" ? null : HubIcon({
      name: "chevron-right",
      size: 12
    })}
                      </div>;
  })}
                </div>
                <div className="hc-composer">
                  <div className="hc-input">Message the agent…</div>
                  <div className="hc-composer__foot">
                    <span>Enter sends · Shift-Enter adds a line · Shift M focuses</span>
                    <span className="hc-send">Send</span>
                  </div>
                </div>
              </section>
            </div>

            <aside className="hc-card hc-rail">
              <div className="hc-tabs">
                <span className="is-active">Session</span>
                <span>Events</span>
                <span>Tools</span>
                <span>Threads</span>
              </div>
              <div className="hc-sect">
                <div className="hc-sect__title">Status</div>
                <p className="hc-note">
                  {done ? "The session finished and is no longer running." : "The agent is working in its sandbox."}
                </p>
                <div className="hc-kv">
                  <span>Started</span>
                  <b>9/24/2026, 12:04:10 PM</b>
                </div>
                <div className="hc-kv">
                  <span>Last activity</span>
                  <b>{done ? "2 seconds ago" : "just now"}</b>
                </div>
                <div className="hc-kv">
                  <span>Stopped</span>
                  <b>{done ? "Outcome satisfied" : "—"}</b>
                </div>
              </div>
              <div className="hc-sect">
                <div className="hc-sect__title">Usage</div>
                <div className="hc-kv">
                  <span>Input tokens</span>
                  <b>{compactNumber(34900 * p)}</b>
                </div>
                <div className="hc-kv">
                  <span>Output tokens</span>
                  <b>{compactNumber(2300 * p)}</b>
                </div>
                <div className="hc-kv">
                  <span>Cache read</span>
                  <b>{compactNumber(16800 * p)}</b>
                </div>
                <div className="hc-kv">
                  <span>Cache write</span>
                  <b>{compactNumber(12600 * p)}</b>
                </div>
                <div className="hc-kv">
                  <span>Cost</span>
                  <b>${(0.06 * p).toFixed(2)}</b>
                </div>
                <div className="hc-kv">
                  <span>Events</span>
                  <b>{Math.round(67 * p)}</b>
                </div>
              </div>
              <div className="hc-sect hc-sect--last">
                <div className="hc-kv hc-kv--title">
                  <span className="hc-sect__title">Cost over time</span>
                  <b>${(0.06 * p).toFixed(2)}</b>
                </div>
                <svg className="hc-spark" viewBox="0 0 240 44" preserveAspectRatio="none" style={{
    clipPath: `inset(0 ${(1 - p) * 100}% 0 0)`
  }}>
                  <path d={`M ${spark} L 240,44 L 0,44 Z`} className="hc-spark__area" />
                  <path d={`M ${spark}`} className="hc-spark__line" />
                </svg>
              </div>
            </aside>
          </div>
        </div>
      </div>
    </div>;
};

export const BuildWithAgents = ({guide}) => {
  const appUrl = "https://recursion.labelbox.com";
  const docsUrl = "https://docs.labelbox.com";
  const docsMcpUrl = docsUrl + "/mcp";
  const apiBase = "https://api.recursion.labelbox.com";
  const tabs = [{
    id: "prompt",
    label: "Prompt",
    copyLabel: "Copy prompt",
    hint: "Paste into Claude Code, Codex or Cursor. It connects the docs MCP server, installs the SDK and checks your API key.",
    text: ["# Set up Recursion Managed Agents", "", "Connect the Recursion docs MCP server to this coding agent, install the Recursion SDK in this project, and check that my API key works. Follow these steps in order, and stop to ask me if one fails.", "", "## Step 1: Check for an API key", "", "Check whether RECURSION_API_KEY is set in this environment. If it is not, ask me to create a key under API keys at " + appUrl + ", export it from my secret manager and start a new session. Never ask me to paste the key into this conversation, and never write it to a file.", "", "## Step 2: Connect the docs MCP server", "", "The docs server needs no key. Use the command for the client you are running in.", "", "Claude Code:", "claude mcp add --transport http --scope user recursion-docs " + docsMcpUrl, "", "Codex:", "codex mcp add recursion-docs --url " + docsMcpUrl, "", "Cursor: add this server to ~/.cursor/mcp.json, then restart Cursor:", '{ "mcpServers": { "recursion-docs": { "url": "' + docsMcpUrl + '" } } }', "", "## Step 3: Set up a client", "", "Read the key from RECURSION_API_KEY and use the base URL " + apiBase + ".", "", "In a TypeScript or JavaScript project, install the SDK and create a client:", "", "npm install @labelbox/recursion-sdk", "", "import { createRecursionClient } from '@labelbox/recursion-sdk';", "const rl = createRecursionClient({", "  apiKey: process.env.RECURSION_API_KEY!,", "  baseUrl: '" + apiBase + "',", "});", "", "In Python or any other language, call the REST API directly with an HTTP client. Paths start at " + apiBase + "/managed-agents/v1, and every request sends the header Authorization: Bearer $RECURSION_API_KEY.", "", "If the key is tenant-scoped, also send the header x-organization-id with my organization id or default.", "", "## Step 4: Check the connection", "", "List the available models (listModels in TypeScript, or GET " + apiBase + "/managed-agents/v1/models over REST) and show me the result. Do not create or update anything.", "", "Then follow " + docsUrl + "/managed-agents/ai-coding-agents and " + docsUrl + "/managed-agents/quickstart to run a first graded session, and report the session id, final status and the agent's answer."].join("\n")
  }, {
    id: "terminal",
    label: "Terminal",
    copyLabel: "Copy commands",
    hint: "The same setup, if you would rather run it yourself.",
    text: ["# 1. Create an API key at " + appUrl.replace("https://", "") + ", then export it", "export RECURSION_API_KEY=...", "", "# 2. Connect your coding agent to the docs MCP server", "claude mcp add --transport http --scope user recursion-docs " + docsMcpUrl, "", "# or, in Codex", "codex mcp add recursion-docs --url " + docsMcpUrl, "", "# 3. TypeScript: install the SDK (in Python or other languages, call the REST API directly)", "npm install @labelbox/recursion-sdk", "", "# 4. Check the key against the API", "curl '" + apiBase + "/managed-agents/v1/models' \\", '  -H "Authorization: Bearer $RECURSION_API_KEY"'].join("\n")
  }];
  const cx = (...names) => names.filter(Boolean).join(" ");
  const [open, setOpen] = useState(false);
  const [tab, setTab] = useState("prompt");
  const [copied, setCopied] = useState(false);
  const [root, setRoot] = useState(null);
  const active = tabs.find(t => t.id === tab) || tabs[0];
  useEffect(() => {
    if (!copied) return undefined;
    const id = setTimeout(() => setCopied(false), 1800);
    return () => clearTimeout(id);
  }, [copied]);
  useEffect(() => {
    if (!open || !root) return undefined;
    const onKey = event => {
      if (event.key !== "Escape") return;
      setOpen(false);
      root.querySelector(".hub-agents__trigger")?.focus();
    };
    const onPointer = event => {
      if (!root.contains(event.target)) setOpen(false);
    };
    document.addEventListener("keydown", onKey);
    document.addEventListener("pointerdown", onPointer);
    return () => {
      document.removeEventListener("keydown", onKey);
      document.removeEventListener("pointerdown", onPointer);
    };
  }, [open, root]);
  const copy = async () => {
    try {
      await navigator.clipboard.writeText(active.text);
      setCopied(true);
    } catch (error) {
      setCopied(false);
    }
  };
  return <div className="hub-agents" ref={setRoot}>
      <button type="button" className="hub-agents__trigger" aria-expanded={open} aria-controls="hub-agents-panel" onClick={() => setOpen(!open)}>
        <span className="hub-agents__marks" aria-hidden="true">
          <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
            <path d="m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z" />
          </svg>
          <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
            <path d="M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" />
          </svg>
          <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
            <path d="M11.503.131 1.891 5.678a.84.84 0 0 0-.42.726v11.188c0 .3.162.575.42.724l9.609 5.55a1 1 0 0 0 .998 0l9.61-5.55a.84.84 0 0 0 .42-.724V6.404a.84.84 0 0 0-.42-.726L12.497.131a1.01 1.01 0 0 0-.996 0M2.657 6.338h18.55c.263 0 .43.287.297.515L12.23 22.918c-.062.107-.229.064-.229-.06V12.335a.59.59 0 0 0-.295-.51l-9.11-5.257c-.109-.063-.064-.23.061-.23" />
          </svg>
        </span>
        Build with agents
        <span className={cx("hub-agents__chevron", open && "is-open")}>{HubIcon({
    name: "chevron-down",
    size: 16
  })}</span>
      </button>

      {open ? <div id="hub-agents-panel" className="hub-agents__panel" role="dialog" aria-label="Set up Recursion Managed Agents with a coding agent">
          <div className="hub-agents__tabs" role="tablist" aria-label="Setup method">
            {tabs.map(t => <button key={t.id} type="button" role="tab" aria-selected={t.id === tab} className={cx("hub-agents__tab", t.id === tab && "is-active")} onClick={() => {
    setTab(t.id);
    setCopied(false);
  }}>
                {t.label}
              </button>)}
          </div>
          <div className="hub-agents__code" role="tabpanel" aria-label={active.label}>
            <pre className="hub-agents__pre" tabIndex={0}>
              {active.text}
            </pre>
            <span className="hub-agents__fade" aria-hidden="true" />
            <button type="button" className="hub-agents__copy" onClick={copy} aria-label={copied ? "Copied" : active.copyLabel}>
              {HubIcon({
    name: copied ? "check" : "copy",
    size: 15
  })}
            </button>
          </div>
          <p className="hub-agents__hint">
            {active.hint}
            {guide ? <a className="hub-agents__guide" href={guide}>
                Read the guide
              </a> : null}
          </p>
        </div> : null}
    </div>;
};

export const HubIcon = ({name, size = 20}) => {
  const paths = {
    recursion: '<ellipse cx="12" cy="12" rx="11" ry="4.565"/><ellipse cx="12" cy="12" rx="11" ry="4.565" transform="rotate(60 12 12)"/><ellipse cx="12" cy="12" rx="11" ry="4.565" transform="rotate(120 12 12)"/>',
    "arrow-right": '<path d="M5 12h14"/><path d="m12 5 7 7-7 7"/>',
    "arrow-up-right": '<path d="M7 7h10v10"/><path d="M7 17 17 7"/>',
    "chevron-right": '<path d="m9 18 6-6-6-6"/>',
    "chevron-down": '<path d="m6 9 6 6 6-6"/>',
    "chevron-left": '<path d="m15 18-6-6 6-6"/>',
    play: '<polygon points="6 3 20 12 6 21 6 3"/>',
    terminal: '<polyline points="4 17 10 11 4 5"/><line x1="12" x2="20" y1="19" y2="19"/>',
    braces: '<path d="M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1"/><path d="M16 21h1a2 2 0 0 0 2-2v-5c0-1.1.9-2 2-2a2 2 0 0 1-2-2V5a2 2 0 0 0-2-2h-1"/>',
    code: '<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>',
    search: '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',
    check: '<path d="M20 6 9 17l-5-5"/>',
    copy: '<rect width="14" height="14" x="8" y="8" rx="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>',
    download: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',
    filter: '<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>',
    panel: '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M15 3v18"/>',
    grid: '<rect width="7" height="7" x="3" y="3" rx="1"/><rect width="7" height="7" x="14" y="3" rx="1"/><rect width="7" height="7" x="14" y="14" rx="1"/><rect width="7" height="7" x="3" y="14" rx="1"/>',
    bot: '<path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/>',
    monitor: '<rect width="20" height="14" x="2" y="3" rx="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/>',
    plug: '<path d="M12 22v-5"/><path d="M9 8V2"/><path d="M15 8V2"/><path d="M18 8v5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V8Z"/>',
    wrench: '<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>',
    zap: '<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>',
    database: '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/>',
    key: '<circle cx="7.5" cy="15.5" r="5.5"/><path d="m21 2-9.6 9.6"/><path d="m15.5 7.5 3 3L22 7l-3-3"/>',
    file: '<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M16 13H8"/><path d="M16 17H8"/><path d="M10 9H8"/>',
    "git-branch": '<line x1="6" x2="6" y1="3" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/>',
    users: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
    chart: '<path d="M3 3v16a2 2 0 0 0 2 2h16"/><path d="M18 17V9"/><path d="M13 17V5"/><path d="M8 17v-3"/>',
    layers: '<path d="m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z"/><path d="m22 17.65-9.17 4.16a2 2 0 0 1-1.66 0L2 17.65"/><path d="m22 12.65-9.17 4.16a2 2 0 0 1-1.66 0L2 12.65"/>',
    book: '<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>',
    tag: '<path d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z"/><circle cx="7.5" cy="7.5" r="1"/>',
    list: '<path d="M3 12h.01"/><path d="M3 18h.01"/><path d="M3 6h.01"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M8 6h13"/>',
    activity: '<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>',
    message: '<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>',
    scale: '<path d="m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z"/><path d="m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z"/><path d="M7 21h10"/><path d="M12 3v18"/><path d="M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2"/>',
    repeat: '<path d="m17 2 4 4-4 4"/><path d="M3 11v-1a4 4 0 0 1 4-4h14"/><path d="m7 22-4-4 4-4"/><path d="M21 13v1a4 4 0 0 1-4 4H3"/>',
    cpu: '<rect width="16" height="16" x="4" y="4" rx="2"/><rect width="6" height="6" x="9" y="9" rx="1"/><path d="M15 2v2"/><path d="M15 20v2"/><path d="M2 15h2"/><path d="M2 9h2"/><path d="M20 15h2"/><path d="M20 9h2"/><path d="M9 2v2"/><path d="M9 20v2"/>',
    box: '<path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/>',
    image: '<rect width="18" height="18" x="3" y="3" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/>',
    shield: '<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/>',
    lightbulb: '<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>',
    sun: '<circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/>',
    asterisk: '<path d="M12 6v12"/><path d="M17.196 9 6.804 15"/><path d="m6.804 9 10.392 6"/>',
    more: '<circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/>',
    updown: '<path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/>',
    "panel-left": '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M9 3v18"/>',
    compass: '<circle cx="12" cy="12" r="10"/><path d="m16.24 7.76-2.12 6.36-6.36 2.12 2.12-6.36 6.36-2.12z"/>',
    card: '<rect width="20" height="14" x="2" y="5" rx="2"/><line x1="2" x2="22" y1="10" y2="10"/>'
  };
  return <svg className="hub-icon" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={name === "recursion" ? 1.9 : 1.75} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" dangerouslySetInnerHTML={{
    __html: paths[name] || ""
  }} />;
};

<div className="hub">
  <HubHero title="Managed AI agents " accent="for every team." description="Recursion runs agents on real work in sandboxed environments and in the apps your team already uses, including GitHub, Slack, and 164+ built-in integrations such as Salesforce, Zendesk, and Snowflake. Agents learn from their past sessions, start on a schedule, from a webhook or event, or by hand, work with the files you give them, and have a grader send the work back when it misses your rubric." primary={{ label: "Start the quickstart", href: "/managed-agents/quickstart" }} secondary={{ label: "API overview", href: "/managed-agents/api" }} setup={<BuildWithAgents guide="/managed-agents/ai-coding-agents" />}>
    <SessionConsole />
  </HubHero>

  <HubSection title="Pick your path" description="Launch your first graded session in the console, or go straight to code.">
    <div className="hub-paths">
      <PathCard title="Quickstart" description="Create an agent, give it a task with a rubric, and read the graded result." href="/managed-agents/quickstart" icon="play" cta="Run your first task" />

      <PathCard title="Build in the console" description="Find the screen for each setup, launch, and inspection task." href="/managed-agents/console" icon="monitor" cta="Tour the console" />

      <PathCard title="API and SDKs" description="Call Recursion through the TypeScript SDK or the REST API from any language." href="/managed-agents/api" icon="braces" cta="Set up a client" />

      <PathCard title="Connect a coding agent" description="Give Claude Code, Codex, or Cursor these docs over MCP, then build with the SDK or REST." href="/managed-agents/ai-coding-agents" icon="plug" cta="Connect over MCP" />
    </div>
  </HubSection>

  <HubSection title="Agents that learn, run on their own, and deliver" description="Memory, automations, and files are part of every organization's Recursion workspace.">
    <CapabilityGrid
      items={[
  { title: "Memory", text: "Agents learn from their finished sessions automatically. Add curated memory, review every change, and roll back.", icon: "lightbulb", href: "/managed-agents/memory" },
  { title: "Automations", text: "Start sessions on a schedule, when Slack, GitHub, or a webhook sends an event, or with Run now.", icon: "repeat", href: "/managed-agents/automations" },
  { title: "Files", text: "Upload inputs once, attach them to any session, and download every deliverable.", icon: "file", href: "/managed-agents/files" },
  { title: "Evaluations and analytics", text: "Score sessions against a rubric and chart usage, cost, and quality across agents.", icon: "chart", href: "/managed-agents/evaluations" },
]}
    />
  </HubSection>

  <HubSection title="Work in the apps your team already uses" description="Connect any of 164+ apps once, choose which tools agents may use in each, and grant them to any agent.">
    <CapabilityGrid
      items={[
  { title: "Sales and CRM", text: "Salesforce, HubSpot, Dynamics 365 Sales, and Pipedrive.", icon: "users", href: "/managed-agents/integrations" },
  { title: "Customer support", text: "Zendesk, Intercom, Freshdesk, and ServiceNow.", icon: "bot", href: "/managed-agents/integrations" },
  { title: "Data and analytics", text: "Snowflake, Databricks, Google BigQuery, and Looker.", icon: "database", href: "/managed-agents/integrations" },
  { title: "Engineering", text: "GitHub, Jira, Linear, GitLab, Sentry, and Datadog.", icon: "git-branch", href: "/managed-agents/github" },
]}
    />
  </HubSection>

  <PlatformBand
    title="Horizon"
    description="Data for reinforcement learning, evals and supervised learning."
    primary={{ label: "Explore Horizon docs", href: "/horizon" }}
    secondary={{ label: "Open the Labelbox app", href: "https://app.labelbox.com" }}
    links={[
{ title: "Get started", text: "Key definitions, prerequisites, and limits.", href: "/docs/overview" },
{ title: "Run evals", text: "Compare and rank generative model outputs across data types.", href: "/docs/multimodal-chat-evaluation-editor" },
{ title: "Label data", text: "Projects, editors, labeling services, and quality tools.", href: "/docs/annotate-overview" },
{ title: "Explore data in Catalog", text: "Filters, slices, batches, and bulk classification.", href: "/docs/explore-your-data-in-catalog" },
{ title: "Python SDK", text: "Install the SDK and follow the developer guides.", href: "/reference/getting-started" },
{ title: "API reference", text: "Every class and method in labelbox-python.", href: "https://labelbox-python.readthedocs.io/en/latest/", external: true },
]}
  />

  <HubFooter
    links={[
{ label: "Recursion", href: "/managed-agents" },
{ label: "Horizon", href: "/horizon" },
{ label: "Release notes", href: "/changelog" },
{ label: "Status", href: "https://status.labelbox.com" },
{ label: "Blog", href: "https://labelbox.com/blog/" },
{ label: "Contact sales", href: "https://labelbox.com/sales" },
]}
  />
</div>
