<!-- GENERATED by scripts/build-llms.mjs from llms/agent-tools.md — do not edit this file. -->

# `lr-tool-call-chip`

- **Import** `import '@aceshooting/lyra-ui/components/lr-tool-call-chip.js';` (stable tag alias; registers the tag)
- **Class** `LyraToolCallChip`, also available unregistered from `@aceshooting/lyra-ui/components/agent-tools/tool-call-chip/tool-call-chip.class.js`
- **Family** `components/agent-tools/` — see `llms/index.md` for its siblings
- **Status** `stable` since `4.0.0` — see the maturity and deprecation policy in `llms/shared.md`
- **Release history** [CHANGELOG.md](../../CHANGELOG.md); family-wide breaking-change summaries: [llms-full.txt](../../llms-full.txt)
- **Deprecations** none
- **Optional peers** none
- **Themeable via** 10 parts, 10 custom properties — see this component's own `@csspart`/`@cssprop` list below
- **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`

---

## `lr-tool-call-chip`

A compact inline pill representing one tool/function call an agent made mid-conversation, e.g.
`web_search: Searching web…` with a `running` spinner. First-party invention (no Web Awesome
equivalent). It owns no detail surface of its own — activating it (click or Enter/Space while
focused) fires `lr-tool-call-chip-select`; a consumer wires that to opening a
`<lr-tool-result-dialog>` (or anything else) at the call site, keeping the chip reusable wherever
a compact call summary is useful, with or without a detail surface behind it.

Removing `category` or `summary` hides that optional text; assigning either attribute again restores
its content.

**Properties:**

- `name: string = ''` — the tool/function name, e.g. `web_search`
- `category: string = ''` — optional grouping label, e.g. `research`
- `status: 'pending'|'running'|'success'|'error'|'denied' = 'pending'` (reflected) — drives the
  glyph, accent color, and `status-text`; same status vocabulary as `<lr-tool-result-dialog>` so a
  call's chip and its detail dialog always agree; unknown runtime values render the pending icon,
  text, and accessible label instead of failing the update
- `summary: string = ''` — short human-readable status text, e.g. `Searching web…`
- `durationMs?: number` (attribute `duration-ms`) — how long the call took, in milliseconds; the
  `duration` part is omitted entirely when unset
- `icon: string = ''` — literal icon hint (e.g. an emoji) rendered when the `icon` slot is empty;
  ignored once anything is assigned to `slot="icon"`
- `callId: string = ''` (attribute `call-id`) — unique identifier for this invocation, echoed back
  in `lr-tool-call-chip-select`'s detail so a listener can correlate the click with the call it fired for

**Events:** `lr-tool-call-chip-select` (`detail: { name: string; callId: string }`) — fired on
click or Enter/Space activation of the pill, exactly once per activation. The `lr-tool-chip-select`
alias (deprecated since 4.0.0) was removed in 9.0.0; listen for `lr-tool-call-chip-select` instead —
the detail is identical.

**Methods:** `focus(options?)`, `blur()`, and `click()` delegate to the internal native chip
button, so programmatic focus/activation reaches the same semantic owner as pointer and keyboard
interaction.

**Slots:** default (rich tooltip/detail content — e.g. the tool's raw arguments or a short preview —
shown in a floating tooltip on hover/focus; nothing renders at all, no hover affordance, when this
slot is empty), `icon` (overrides the built-in per-status glyph entirely via native slot-fallback
content — assigned content wins; otherwise the `icon` prop is rendered as a literal hint; otherwise
the built-in glyph for the current `status` is used)

**CSS parts:** `base` (the clickable `<button>`), `icon`, `label` (wrapper around `category`, `name`,
`summary`), `category`, `name`, `summary`, `meta` (wrapper around `status-text` and `duration`),
`status-text`, `duration`, `tooltip` (the floating detail popup, only meaningful while open)

**Themeable custom properties:** `--lr-tool-call-chip-spin` (default `var(--lr-transition-ambient)`,
i.e. `1.8s ease-in-out` at the shipped token value and `0.001ms linear` under
`prefers-reduced-motion` — running-icon animation duration/timing) and `--lr-transition-ambient`
(default `1.8s ease-in-out` — pending-icon pulse duration/timing).
`--lr-tool-call-chip-accent`, `--lr-tool-call-chip-bg`, and `--lr-tool-call-chip-border` are public
component hooks whose private defaults follow `status` (e.g. `pending` →
`--lr-color-text-quiet`/`--lr-color-surface`/`--lr-color-border`; `running` → brand; `success` →
success; `error` → danger; `denied` → warning). Set them on an ancestor to retheme a subtree or
directly on one chip; either public value remains authoritative in every status. Shared tokens
referenced: `--lr-color-text-quiet`, `--lr-color-surface`, `--lr-color-border`,
`--lr-color-brand`/`-brand-quiet`, `--lr-color-success`/`-success-quiet`,
`--lr-color-danger`/`-danger-quiet`, `--lr-color-warning`/`-warning-quiet`, `--lr-color-text`,
`--lr-space-xs/-s/-m`, `--lr-radius`, `--lr-shadow`, `--lr-focus-ring-*`,
`--lr-transition-fast`.

> Retheming a group of chips from outside `<lr-tool-call-chip>` (e.g. per-tool or per-status
> colors)? Set the component hooks above on their ancestor wrapper. Use `--lr-theme-*` instead only
> when changing a shared semantic palette input for the entire subtree.

The anchored detail tooltip is a floating surface and paints from the **shared overlay-surface family** (16.0.0):
`--lr-overlay-surface` (default `var(--lr-color-surface-overlay)`), `--lr-overlay-border` (default
`var(--lr-color-border)`) and `--lr-overlay-shadow-anchored` (default `var(--lr-shadow-m)`). None is
declared on `:host`, so one declaration on `:root` — or on any ancestor, to scope it — retints this
surface together with every other floating surface in the library. `--lr-overlay-radius` (default `var(--lr-radius)`) is the matching corner radius.

`--lr-positioning-strategy` (16.0.0) — the detail tooltip reads this same cascading
`absolute`/`fixed` override documented on `<lr-popover>` when it is (re)positioned, falling back to
its own `fixed` default when nothing is set. There is no per-instance `positioning-strategy`
property on `<lr-tool-call-chip>`; set the custom property on `:root`, a theme, or one clipping
ancestor to change every unset chip beneath it.

**Optional peer deps:** none.

```html
<lr-tool-call-chip
  name="web_search"
  category="research"
  status="running"
  summary="Searching web…"
  duration-ms="820"
  call-id="call_123"
>
  <pre slot="icon" style="display:none"></pre>
  <code>{"query": "lyra ui components"}</code>
</lr-tool-call-chip>
<script type="module">
  document
    .querySelector("lr-tool-call-chip")
    .addEventListener("lr-tool-call-chip-select", (e) => openDetail(e.detail.callId));
</script>
```

The default slot's tooltip uses the same `'top-start'` placement as `<lr-combobox>`'s listbox, and
appears/disappears instantly
on hover/focus/blur/mouseleave with no fade transition and no "pointer moved into the tooltip"
tracking — it's documented as read-only preview content, not an interactive surface meant to retain
focus of its own. `denied` gets its own warning-toned glyph and color (a policy rejection, not a
runtime failure) distinct from `error`'s danger tone, matching `<lr-tool-result-dialog>`'s
identical status vocabulary so a call reads the same way in both places. Duration formatting is
sub-1000ms `"820ms"`, else trimmed to at most one decimal of seconds (`"1.5s"`, `"2s"`).

**Known gotchas:**

- meaningful default-slot text or element content enables the preview tooltip; whitespace-only
  text does not. A text preview needs no wrapper, and the preview remains inert and noninteractive
- the native button always keeps its purpose-specific generated name (`"name — summary — Status —
duration"`). A host `aria-label` remains on the host and is not cloned onto that button; even an
  explicit empty host label never leaves the actionable button unnamed
- the `icon` slot is decorative by contract. Its wrapper is both `aria-hidden` and `inert`, so do
  not place links, buttons, or other controls there; use the chip activation or detail slot instead
- Escape only dismisses the tooltip when it's open; it does not fire any event or otherwise affect
  `status`/`open` state, since the chip has no "open" state of its own beyond the tooltip

---
