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

# `lr-prompt-studio`

- **Import** `import '@aceshooting/lyra-ui/components/lr-prompt-studio.js';` (stable tag alias; registers the tag)
- **Class** `LyraPromptStudio`, also available unregistered from `@aceshooting/lyra-ui/components/agent-tools/prompt-studio/prompt-studio.class.js`
- **Family** `components/agent-tools/` — see `llms/index.md` for its siblings
- **Status** `stable` since `7.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** 19 parts, 5 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-prompt-studio`

Prompt-development workbench for ordered role messages, `{{variable}}` substitution, saved
versions, resolved preview, and save/run intents. Message and variable edits emit a cancelable
`lr-change` proposal carrying their complete next state before updating the component's current
arrays; persistence and execution remain host-owned.

Variable values resolve recursively; undefined and cyclic placeholders remain literal within preview
bounds. Each preview projection permits at most 64 nested variable resolutions, 10,000 placeholder
substitutions, and 1,048,576 UTF-16 code units each of aggregate resolved message output and
aggregate memoized intermediate text. Limits are checked before constructing oversized text.
Exceeding a limit replaces the resolved preview with a localized visible fallback; raw messages,
variables, editing and save/run payloads are unchanged.

**Properties:** `messages: readonly PromptStudioMessage[] = []` and
`variables: readonly PromptStudioVariable[] = []` are property-only editor state: user edits emit a
cancelable `lr-change` before updating the current arrays, while the host remains responsible for
persistence.
`versions: readonly PromptStudioVersion[] = []` is a property-only host-controlled input;
empty/blank message and version ids are omitted and later duplicates use deterministic first-wins
identity before rendering, editing, focus, selection, and events;
runtime `null`/non-array values for any of the three not-yet-loaded collections render as empty;
`selectedVersionId: string | null = null` (attribute `selected-version-id`); `label: string = ''`;
`heading: string = ''` — visible toolbar heading, falling back to the localized Prompt Studio
label when unset;
`running: boolean = false`, `disabled: boolean = false`, and `reorderable: boolean = false`
(all reflected). `reorderable` adds native move-up/move-down controls for each message. A move first
emits a cancelable request, so a host can veto it while persisting the proposed order and later
assign the accepted `messages` array. Native prose-editing assistance is forwarded to every message
textarea and variable input through `spellcheck: boolean = true`, `autocapitalize: string = ''`,
and `autoCorrect: string = ''` (attribute `autocorrect`); `wrap: PromptStudioWrap = 'soft'` applies
to message textareas only.

**Exported types:** `PromptStudioRole = ChatMessageRole | 'tool'`, where the shared
`ChatMessageRole` is `'system' | 'user' | 'assistant'`;
`PromptStudioMessage = { id, role, content, name? }`; `PromptStudioVariable = { name, value,
description? }`; `PromptStudioVersion = { id: string; label: string; messages:
readonly PromptStudioMessage[]; variables?: readonly PromptStudioVariable[]; createdAt?: string }`; and
`PromptStudioState = { messages, variables }`; `PromptStudioWrap = 'hard' | 'soft' | 'off'`; and
`PromptStudioMessageReorderDetail = { messages, messageId, fromIndex, toIndex }`.

**Events:** cancelable `lr-change` (`{ messages, variables }`, the complete proposed next state,
fired before it is applied — prevent it to keep the current state unchanged), `lr-run`, `lr-save`
(both carry complete messages/variables); `lr-version-select` (`{ version }`); and cancelable
`lr-message-reorder` (`{ messages, messageId, fromIndex, toIndex }`) before an accepted move
updates the component and emits `lr-change`. Prevent `lr-message-reorder` to keep the current
order; the listener may persist `detail.messages` and assign it back when ready. Plus `focus` and
`blur` (no detail), re-dispatched
from the host — bubbling and composed — whenever a message textarea or a variable input gains or
loses focus. They exist because the native `focus`/`blur` events neither bubble nor cross the shadow
boundary, so without the re-dispatch an
`editor.addEventListener('focus', …)` would never fire at all. They are re-dispatches of real
focus movement, not a synthetic host-level focus signal: moving between two fields inside the
studio emits a `blur` and then a `focus`.

**CSS parts:** `base`, `toolbar`, `editor`, `messages`, `message`, `message-role`,
`message-content`, `message-actions`, `move-message-up`, `move-message-down`, `remove-message`,
`add-message`, `variables`, `variable`, `versions`, `version`, `preview`, `save`, `run`.

Each `message-content` textarea deliberately keeps native vertical resizing. Prompt Studio exposes
neither a configurable `resize` surface nor auto-grow behavior; use a dedicated editor when either
is required.

Each message's role select and content editor has a localized contextual accessible name containing
its one-based message index and purpose (plus the current role for content), so repeated controls do
not collapse to indistinguishable generic names.

**Slots:** none. **Optional peer deps:** none.

```ts
import "@aceshooting/lyra-ui/components/agent-tools/prompt-studio/prompt-studio.js";
```

**Additional API surface:**

- `--lr-prompt-studio-field-hover-border` — Enabled field hover border. Default: `var(--lr-color-brand)`.
- `--lr-prompt-studio-version-selected-border` — Selected version border. Default: `var(--lr-color-brand)`.
- `--lr-prompt-studio-version-selected-bg` — Selected version background. Default: `var(--lr-color-brand-quiet)`.
- `--lr-prompt-studio-version-selected-color` — Selected version foreground. Default: `var(--lr-color-text)`.
- `--lr-prompt-studio-version-selected-hover-bg` — Selected version hover background. Default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`.
