@livelayer/react 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +257 -26
- package/dist/index.d.ts +148 -0
- package/dist/index.js +2 -1
- package/dist/index.mjs +1381 -1001
- package/dist/styles.css +50 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,58 +1,289 @@
|
|
|
1
1
|
# @livelayer/react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Drop-in voice/video AI agent widget for React apps. The full-fidelity widget that powers [app.livelayer.studio](https://app.livelayer.studio), packaged for direct mount in your app's DOM (no iframe).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Quickstart (5 minutes)
|
|
6
|
+
|
|
7
|
+
Three files, one published agent, working voice nav.
|
|
8
|
+
|
|
9
|
+
**1. Install**
|
|
6
10
|
|
|
7
11
|
```bash
|
|
8
12
|
npm install @livelayer/react
|
|
13
|
+
# or pnpm add @livelayer/react / yarn add @livelayer/react
|
|
9
14
|
```
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
**2. Get an agent ID** — go to [app.livelayer.studio](https://app.livelayer.studio), publish an agent, copy its ID (looks like `cmobfeluv000bju04ct1cqdb0`).
|
|
17
|
+
|
|
18
|
+
**3. Mount the widget** (Next.js App Router shown — works the same way in any React app):
|
|
12
19
|
|
|
13
20
|
```tsx
|
|
14
|
-
|
|
21
|
+
"use client";
|
|
22
|
+
|
|
23
|
+
import { AvatarWidget } from "@livelayer/react";
|
|
24
|
+
import "@livelayer/react/styles.css";
|
|
25
|
+
import { useRouter, usePathname } from "next/navigation";
|
|
26
|
+
|
|
27
|
+
export default function Layout({ children }: { children: React.ReactNode }) {
|
|
28
|
+
const router = useRouter();
|
|
29
|
+
const pathname = usePathname();
|
|
15
30
|
|
|
16
|
-
function App() {
|
|
17
31
|
return (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
32
|
+
<>
|
|
33
|
+
{children}
|
|
34
|
+
<AvatarWidget
|
|
35
|
+
agentId="cmobfeluv000bju04ct1cqdb0"
|
|
36
|
+
pathname={pathname}
|
|
37
|
+
onNavigate={(href) => router.push(href)}
|
|
38
|
+
hideOn={["/privacy", "/terms", "/legal/*"]}
|
|
39
|
+
/>
|
|
40
|
+
</>
|
|
22
41
|
);
|
|
23
42
|
}
|
|
24
43
|
```
|
|
25
44
|
|
|
26
|
-
|
|
45
|
+
That's it. The widget docks bottom-right, the agent can navigate users to other pages by voice, and it stays out of the way on legal pages. The LiveKit session survives every SPA route change.
|
|
27
46
|
|
|
28
|
-
|
|
29
|
-
| --------------- | --------------------------------------- | -------- | --------------------------------------------------- |
|
|
30
|
-
| `agentId` | `string` | Yes | The published agent ID to connect to |
|
|
31
|
-
| `mode` | `"WIDGET" \| "EMBEDDED"` | No | Override the experience mode from the agent config |
|
|
32
|
-
| `onAgentEvent` | `(event: AgentEventDetail) => void` | No | Callback fired when the agent emits a data channel event |
|
|
33
|
-
| `className` | `string` | No | CSS class name on the wrapper div |
|
|
34
|
-
| `style` | `React.CSSProperties` | No | Inline styles on the wrapper div |
|
|
47
|
+
> **Common gotcha:** if the widget renders unstyled, check that you imported `@livelayer/react/styles.css`. It's a separate import to give consumers the option to scope styles.
|
|
35
48
|
|
|
36
|
-
|
|
49
|
+
---
|
|
37
50
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
51
|
+
## Recipes
|
|
52
|
+
|
|
53
|
+
### 1. Voice navigation in Next.js / React Router
|
|
54
|
+
|
|
55
|
+
Pass your router into `onNavigate`. When the agent emits a `navigate` command, the widget calls your callback. The session never reloads.
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
// Next.js App Router
|
|
59
|
+
import { useRouter } from "next/navigation";
|
|
60
|
+
const router = useRouter();
|
|
61
|
+
<AvatarWidget agentId="..." onNavigate={(href) => router.push(href)} />
|
|
62
|
+
|
|
63
|
+
// React Router v6
|
|
64
|
+
import { useNavigate } from "react-router-dom";
|
|
65
|
+
const navigate = useNavigate();
|
|
66
|
+
<AvatarWidget agentId="..." onNavigate={navigate} />
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
If you don't pass `onNavigate`, the widget falls back to (1) clicking a matching `<a href="...">` in the DOM (Next.js `<Link>` and React Router `<Link>` both intercept these), then (2) `history.pushState` for plain HTML pages. **It never uses `window.location` — that's a hard reload that would kill the call.**
|
|
70
|
+
|
|
71
|
+
You also need to register a `navigate` tool on your agent so it can emit the command. In your agent's tool schema:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"name": "navigate",
|
|
76
|
+
"description": "Take the user to a different page on this site.",
|
|
77
|
+
"parameters": {
|
|
78
|
+
"type": "object",
|
|
79
|
+
"properties": { "href": { "type": "string" } },
|
|
80
|
+
"required": ["href"]
|
|
81
|
+
}
|
|
42
82
|
}
|
|
43
83
|
```
|
|
44
84
|
|
|
45
|
-
|
|
85
|
+
When the LLM calls `navigate({ href: "/pricing" })`, your agent server publishes `{ type: "navigate", href: "/pricing" }` on the data channel. The widget handles the rest.
|
|
86
|
+
|
|
87
|
+
### 2. Hide on sensitive routes
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<AvatarWidget
|
|
91
|
+
agentId="..."
|
|
92
|
+
pathname={usePathname()}
|
|
93
|
+
hideOn={["/privacy", "/terms", "/cookies", "/legal/**"]}
|
|
94
|
+
/>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Glob rules:
|
|
98
|
+
- `*` matches one path segment: `/admin/*` → `/admin/users` but not `/admin/users/edit`
|
|
99
|
+
- `**` matches any depth: `/admin/**` → `/admin`, `/admin/users`, `/admin/users/edit`
|
|
100
|
+
- A `RegExp` or function works too: `hideOn={[/^\/blog\/draft-.+$/, (p) => p.startsWith("/internal")]}`
|
|
101
|
+
|
|
102
|
+
The LiveKit session **stays alive** while hidden. When the user navigates back to an allowed route, the call resumes seamlessly.
|
|
103
|
+
|
|
104
|
+
`showOn` is the inverse — restrict to a whitelist. `hideOn` wins on collisions.
|
|
105
|
+
|
|
106
|
+
### 3. Let the agent see the page
|
|
107
|
+
|
|
108
|
+
When the agent asks "what's the user looking at?", the widget walks the DOM and sends back a structured snapshot. You don't need to do anything for this to work, but you can guide it with `<LiveLayerRegion>`:
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
import { LiveLayerRegion } from "@livelayer/react";
|
|
112
|
+
|
|
113
|
+
<LiveLayerRegion id="pricing" intent="show pricing tiers">
|
|
114
|
+
<PricingTable />
|
|
115
|
+
</LiveLayerRegion>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This renders a `<div data-ll-region="pricing" data-ll-intent="show pricing tiers">` that the page-context extractor surfaces with priority. The `intent` is author-language for the agent.
|
|
46
119
|
|
|
47
|
-
|
|
120
|
+
To register the agent-side tool:
|
|
48
121
|
|
|
49
122
|
```json
|
|
50
123
|
{
|
|
51
|
-
"
|
|
52
|
-
"
|
|
124
|
+
"name": "getPageContext",
|
|
125
|
+
"description": "Snapshot of what the user is currently looking at — useful when they ask 'what is this' or 'show me the X'.",
|
|
126
|
+
"parameters": { "type": "object", "properties": {} }
|
|
53
127
|
}
|
|
54
128
|
```
|
|
55
129
|
|
|
130
|
+
When the LLM calls it, your agent publishes `{ type: "request_page_context" }` and waits for the widget's `{ type: "page_context", context: {...} }` response (typically <100ms).
|
|
131
|
+
|
|
132
|
+
You can override the default extractor entirely:
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
<AvatarWidget
|
|
136
|
+
getPageContext={() => ({
|
|
137
|
+
url: window.location.href,
|
|
138
|
+
pathname: window.location.pathname,
|
|
139
|
+
title: document.title,
|
|
140
|
+
regions: [{ id: "cart", text: cartSummary }],
|
|
141
|
+
visibleText: "",
|
|
142
|
+
visibleLinks: [],
|
|
143
|
+
visibleFields: [],
|
|
144
|
+
})}
|
|
145
|
+
/>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Or attach extra app state without replacing the walker:
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
<AvatarWidget
|
|
152
|
+
pageContextExtras={{ userId: user.id, cartItemCount: items.length }}
|
|
153
|
+
/>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 4. Persist the session across pages (multi-page apps)
|
|
157
|
+
|
|
158
|
+
For SPAs (Next.js, Remix, React Router), mount the widget at the app root and the session survives route changes automatically. For multi-page apps where the entire React tree unmounts, use `controlledSession` to own the LiveKit Room yourself and keep it alive across reloads. See [the `ControlledSession` interface](src/AvatarWidget.tsx) for the contract.
|
|
159
|
+
|
|
160
|
+
### 5. Custom branding
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
<AvatarWidget
|
|
164
|
+
branding={{
|
|
165
|
+
primaryColor: "#0ea5e9",
|
|
166
|
+
accentColor: "#f59e0b",
|
|
167
|
+
productName: "Acme Concierge",
|
|
168
|
+
logoUrl: "/logo.png",
|
|
169
|
+
}}
|
|
170
|
+
/>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## API reference
|
|
176
|
+
|
|
177
|
+
### `<AvatarWidget>` (primary)
|
|
178
|
+
|
|
179
|
+
All props are optional except `agentId`.
|
|
180
|
+
|
|
181
|
+
| Prop | Type | Description |
|
|
182
|
+
|---|---|---|
|
|
183
|
+
| `agentId` | `string` | **Required.** The published agent ID. |
|
|
184
|
+
| `apiKey` | `string` | API key for cross-origin auth. Required if your agent isn't public. |
|
|
185
|
+
| `baseUrl` | `string` | Base URL of the LiveLayer API. Defaults to `https://app.livelayer.studio`. |
|
|
186
|
+
| `pathname` | `string` | Current pathname. **Required for Next.js App Router and React Router v6+.** Pass `usePathname()` / `useLocation().pathname`. |
|
|
187
|
+
| `showOn` | `RoutePattern[]` | Render only on matching paths. |
|
|
188
|
+
| `hideOn` | `RoutePattern[]` | Never render on matching paths. Wins over `showOn`. |
|
|
189
|
+
| `onNavigate` | `(href: string) => void` | Called on agent `navigate` command. Wire to your router. |
|
|
190
|
+
| `onScrollToSelector` | `(sel, behavior?) => void` | Called on agent `scroll_to` command. Default: `scrollIntoView({ behavior: "smooth" })`. |
|
|
191
|
+
| `getPageContext` | `() => PageContext \| Promise<PageContext>` | Override the default DOM walker. |
|
|
192
|
+
| `pageContextExtras` | `Record<string, unknown>` | Extra app state attached to every page context snapshot. |
|
|
193
|
+
| `position` | `"top-left" \| "top-right" \| "bottom-left" \| "bottom-right" \| "custom"` | Where the widget docks. Defaults to `"bottom-right"`. |
|
|
194
|
+
| `defaultDisplayMode` | `"hidden" \| "minimized" \| "expanded"` | Initial display mode. |
|
|
195
|
+
| `branding` | `BrandingConfig` | Colors, product name, logo. |
|
|
196
|
+
| `teamMembers` | `TeamMember[]` | Multi-agent picker. |
|
|
197
|
+
| `controlledSession` | `ControlledSession` | Bring-your-own LiveKit Room. |
|
|
198
|
+
| `onAgentCommand` | `(cmd) => void` | Receive non-universal data-channel commands. |
|
|
199
|
+
| `onAgentEvent` | `(e) => void` | Receive ALL data-channel events (including the universal ones). |
|
|
200
|
+
|
|
201
|
+
### `<LiveLayerRegion>` (page-context primitive)
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
<LiveLayerRegion id="pricing" intent="show pricing tiers" as="section">
|
|
205
|
+
...
|
|
206
|
+
</LiveLayerRegion>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Renders a wrapper element with `data-ll-region` + `data-ll-intent` that the page-context extractor prioritizes.
|
|
210
|
+
|
|
211
|
+
### Hooks (power users)
|
|
212
|
+
|
|
213
|
+
`useLiveKitSession`, `useDisplayMode`, `useAgentInfo`, `usePathname`, `useRouteMatch`, `useAudioLevel`, `useMicrophoneState`, `useCameraState`, `useScreenShareState`, `useMediaDevices`, `useTranscript`. All exported from the package root.
|
|
214
|
+
|
|
215
|
+
### Types
|
|
216
|
+
|
|
217
|
+
`AvatarWidgetProps`, `RoutePattern`, `PageContext`, `AgentCommand`, `AgentEventDetail`, `TeamMember`, `BrandingConfig`, `WidgetPosition`, `DisplayMode`. All exported from the package root.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Privacy
|
|
222
|
+
|
|
223
|
+
The default page-context walker **never** extracts:
|
|
224
|
+
|
|
225
|
+
- Form values (only labels and field types)
|
|
226
|
+
- Inputs with `type="password"`
|
|
227
|
+
- Inputs with `autocomplete="cc-*"` or `autocomplete="off"`
|
|
228
|
+
- Elements (and their subtrees) with `data-ll-private="true"`
|
|
229
|
+
- The widget itself (`.ll-widget`)
|
|
230
|
+
|
|
231
|
+
To redact additional content:
|
|
232
|
+
|
|
233
|
+
```tsx
|
|
234
|
+
<div data-ll-private="true">
|
|
235
|
+
<UserBankAccount />
|
|
236
|
+
</div>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Or override `getPageContext` entirely to control exactly what reaches the agent.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Migrating from 0.2.x
|
|
244
|
+
|
|
245
|
+
0.3.0 is **additive**. All existing 0.2.x code continues to work without changes.
|
|
246
|
+
|
|
247
|
+
**Soft breaking — observability only:** the data-channel commands `navigate`, `scroll_to`, and `request_page_context` are now handled internally by the widget and no longer reach `onAgentCommand`. If you previously observed them via that callback (unlikely — they were never emitted in 0.2.x), switch to `onAgentEvent`, which still fires for every message.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Errors and warnings
|
|
252
|
+
|
|
253
|
+
Every console message from this package starts with `[LiveLayer]` and includes a doc URL. Examples:
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
[LiveLayer] Agent emitted "navigate" without href. Skipping.
|
|
257
|
+
Check your agent's tool schema.
|
|
258
|
+
See https://livelayer.studio/docs/errors/navigate-missing-href
|
|
259
|
+
|
|
260
|
+
[LiveLayer] scroll_to: no element matched "#pricing-table".
|
|
261
|
+
The user may be on a different page.
|
|
262
|
+
See https://livelayer.studio/docs/errors/scroll-no-match
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
If you see one of these in production, the doc URL has the explanation and remediation.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Legacy: `<LiveLayerWidget>`
|
|
270
|
+
|
|
271
|
+
The thin web-component wrapper from 0.1.x is still exported for backwards compatibility. New apps should use `<AvatarWidget>`.
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
import { LiveLayerWidget } from "@livelayer/react";
|
|
275
|
+
<LiveLayerWidget agentId="..." />
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Peer dependencies
|
|
281
|
+
|
|
282
|
+
- `react` >= 18.0.0
|
|
283
|
+
- `react-dom` >= 18.0.0
|
|
284
|
+
|
|
285
|
+
No router peer dependency. Works with Next.js App Router, Next.js Pages Router, React Router (any version), Remix, TanStack Router, or no router at all.
|
|
286
|
+
|
|
56
287
|
## License
|
|
57
288
|
|
|
58
289
|
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -3,11 +3,14 @@ import { AgentState } from '@livelayer/sdk';
|
|
|
3
3
|
import { Component } from 'react';
|
|
4
4
|
import { ConnectionState } from '@livelayer/sdk';
|
|
5
5
|
import { CSSProperties } from 'react';
|
|
6
|
+
import { ElementType } from 'react';
|
|
6
7
|
import { ErrorInfo } from 'react';
|
|
7
8
|
import { FC } from 'react';
|
|
9
|
+
import { ForwardRefExoticComponent } from 'react';
|
|
8
10
|
import { JSX } from 'react/jsx-runtime';
|
|
9
11
|
import { LiveKitSession } from '@livelayer/sdk';
|
|
10
12
|
import { ReactNode } from 'react';
|
|
13
|
+
import { RefAttributes } from 'react';
|
|
11
14
|
import { Room } from 'livekit-client';
|
|
12
15
|
import { SessionOptions } from '@livelayer/sdk';
|
|
13
16
|
import { TranscriptEntry } from '@livelayer/sdk';
|
|
@@ -92,6 +95,52 @@ export declare interface AvatarWidgetProps {
|
|
|
92
95
|
allowScreenShare?: boolean;
|
|
93
96
|
allowTyping?: boolean;
|
|
94
97
|
allowMic?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Patterns where the widget MAY render. If set, widget renders ONLY on
|
|
100
|
+
* matching paths. See `RoutePattern` for accepted forms (string globs,
|
|
101
|
+
* RegExp, or function predicate). Mutually compatible with `hideOn`.
|
|
102
|
+
*
|
|
103
|
+
* Pass `pathname` alongside this prop in Next.js / React Router apps.
|
|
104
|
+
*/
|
|
105
|
+
showOn?: RoutePattern[];
|
|
106
|
+
/**
|
|
107
|
+
* Patterns where the widget will NEVER render. Wins over showOn.
|
|
108
|
+
* Common safe defaults: `["/privacy", "/terms", "/legal/*"]`.
|
|
109
|
+
*/
|
|
110
|
+
hideOn?: RoutePattern[];
|
|
111
|
+
/**
|
|
112
|
+
* Current pathname. REQUIRED for Next.js App Router and React Router v6+
|
|
113
|
+
* because their internal routers update before window.location does.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* import { usePathname } from "next/navigation";
|
|
117
|
+
* <AvatarWidget pathname={usePathname()} hideOn={["/privacy"]} />
|
|
118
|
+
*/
|
|
119
|
+
pathname?: string;
|
|
120
|
+
/**
|
|
121
|
+
* Called when the agent emits a `navigate` command. Wire to your
|
|
122
|
+
* router. If omitted, the widget falls back to (1) clicking a
|
|
123
|
+
* matching anchor (so Next/RR Link interceptors fire) and then
|
|
124
|
+
* (2) `history.pushState` for plain HTML sites. `window.location`
|
|
125
|
+
* is NEVER used — that would trigger a full reload and kill the
|
|
126
|
+
* session.
|
|
127
|
+
*/
|
|
128
|
+
onNavigate?: (href: string) => void;
|
|
129
|
+
/**
|
|
130
|
+
* Called when the agent emits a `scroll_to` command. Default:
|
|
131
|
+
* scrolls the matched element into view smoothly. Override to
|
|
132
|
+
* customize easing or skip the scroll entirely.
|
|
133
|
+
*/
|
|
134
|
+
onScrollToSelector?: (selector: string, behavior?: "smooth" | "instant") => void;
|
|
135
|
+
/**
|
|
136
|
+
* Override the default DOM walker. Receives the consumer's
|
|
137
|
+
* `pageContextExtras` and returns a structured context for the
|
|
138
|
+
* agent. Useful for filtering sensitive content or prepending app
|
|
139
|
+
* state that's not in the DOM.
|
|
140
|
+
*/
|
|
141
|
+
getPageContext?: (extras?: Record<string, unknown>) => PageContext | Promise<PageContext>;
|
|
142
|
+
/** Free-form metadata bag the agent should always know about. */
|
|
143
|
+
pageContextExtras?: Record<string, unknown>;
|
|
95
144
|
onConnect?: () => void;
|
|
96
145
|
onDisconnect?: () => void;
|
|
97
146
|
onTranscript?: (entries: TranscriptEntry[]) => void;
|
|
@@ -137,6 +186,8 @@ export declare interface CameraStateHandle {
|
|
|
137
186
|
clearError: () => void;
|
|
138
187
|
}
|
|
139
188
|
|
|
189
|
+
export declare function clearPageContextCache(): void;
|
|
190
|
+
|
|
140
191
|
export { ConnectionState }
|
|
141
192
|
|
|
142
193
|
/**
|
|
@@ -180,6 +231,15 @@ export declare class ErrorBoundary extends Component<Props, State> {
|
|
|
180
231
|
render(): ReactNode;
|
|
181
232
|
}
|
|
182
233
|
|
|
234
|
+
declare interface ExtractOptions {
|
|
235
|
+
/** Override doc — for tests. */
|
|
236
|
+
doc?: Document;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export declare function extractPageContext(extras?: Record<string, unknown>, opts?: ExtractOptions): PageContext;
|
|
240
|
+
|
|
241
|
+
export declare function getCachedPageContext(extras?: Record<string, unknown>, opts?: ExtractOptions): PageContext;
|
|
242
|
+
|
|
183
243
|
export declare interface LegacyAgentEventDetail {
|
|
184
244
|
eventName: string;
|
|
185
245
|
data: Record<string, unknown>;
|
|
@@ -187,6 +247,22 @@ export declare interface LegacyAgentEventDetail {
|
|
|
187
247
|
|
|
188
248
|
declare type LevelSubscriber = (level: number) => void;
|
|
189
249
|
|
|
250
|
+
export declare const LiveLayerRegion: ForwardRefExoticComponent<LiveLayerRegionProps & RefAttributes<HTMLElement>>;
|
|
251
|
+
|
|
252
|
+
export declare interface LiveLayerRegionProps {
|
|
253
|
+
/** Stable identifier for the region. Becomes `data-ll-region`. */
|
|
254
|
+
id: string;
|
|
255
|
+
/** One-line description of what the agent should know about this region. */
|
|
256
|
+
intent?: string;
|
|
257
|
+
/** Element to render. Defaults to "div". */
|
|
258
|
+
as?: ElementType;
|
|
259
|
+
/** Extra class name on the wrapper. */
|
|
260
|
+
className?: string;
|
|
261
|
+
/** Inline styles. */
|
|
262
|
+
style?: CSSProperties;
|
|
263
|
+
children: ReactNode;
|
|
264
|
+
}
|
|
265
|
+
|
|
190
266
|
/**
|
|
191
267
|
* React component that renders a `<livelayer-widget>` custom element.
|
|
192
268
|
*
|
|
@@ -220,6 +296,8 @@ export declare interface LiveLayerWidgetProps {
|
|
|
220
296
|
style?: React.CSSProperties;
|
|
221
297
|
}
|
|
222
298
|
|
|
299
|
+
export declare function matchesPattern(pattern: RoutePattern, pathname: string): boolean;
|
|
300
|
+
|
|
223
301
|
export declare interface MediaDevicesHandle {
|
|
224
302
|
mics: MediaDeviceInfo[];
|
|
225
303
|
cameras: MediaDeviceInfo[];
|
|
@@ -257,6 +335,42 @@ declare interface Options_2 {
|
|
|
257
335
|
disablePersistence?: boolean;
|
|
258
336
|
}
|
|
259
337
|
|
|
338
|
+
/**
|
|
339
|
+
* Snapshot of what the user is currently looking at, sent to the agent in
|
|
340
|
+
* response to a `request_page_context` command.
|
|
341
|
+
*
|
|
342
|
+
* Form values, password inputs, and elements marked `data-ll-private="true"`
|
|
343
|
+
* are NEVER included. See README → Privacy.
|
|
344
|
+
*/
|
|
345
|
+
export declare interface PageContext {
|
|
346
|
+
/** Full URL at the moment the snapshot was taken. */
|
|
347
|
+
url: string;
|
|
348
|
+
/** document.title at snapshot time. */
|
|
349
|
+
title: string;
|
|
350
|
+
/** Pathname only (no host, no query, no hash). */
|
|
351
|
+
pathname: string;
|
|
352
|
+
/** Author-curated regions via <LiveLayerRegion> — agent should prefer these. */
|
|
353
|
+
regions: Array<{
|
|
354
|
+
id: string;
|
|
355
|
+
intent?: string;
|
|
356
|
+
text: string;
|
|
357
|
+
}>;
|
|
358
|
+
/** Visible content fallback — auto-extracted text from headings/paragraphs. */
|
|
359
|
+
visibleText: string;
|
|
360
|
+
/** Anchor hrefs visible in viewport, top-to-bottom, max 20. */
|
|
361
|
+
visibleLinks: Array<{
|
|
362
|
+
href: string;
|
|
363
|
+
text: string;
|
|
364
|
+
}>;
|
|
365
|
+
/** Form fields visible in viewport — labels and types only, never values. */
|
|
366
|
+
visibleFields: Array<{
|
|
367
|
+
label: string;
|
|
368
|
+
type: string;
|
|
369
|
+
}>;
|
|
370
|
+
/** Free-form metadata bag from the consumer's pageContextExtras prop. */
|
|
371
|
+
extras?: Record<string, unknown>;
|
|
372
|
+
}
|
|
373
|
+
|
|
260
374
|
declare interface Props {
|
|
261
375
|
children: ReactNode;
|
|
262
376
|
/** Callback fired when an error is caught. Useful for telemetry. */
|
|
@@ -265,6 +379,22 @@ declare interface Props {
|
|
|
265
379
|
fallback?: ReactNode;
|
|
266
380
|
}
|
|
267
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Pattern matched against the current pathname to decide if the widget
|
|
384
|
+
* renders.
|
|
385
|
+
*
|
|
386
|
+
* - `string` — exact match OR glob with `*` (one segment) and `**` (any depth)
|
|
387
|
+
* - `RegExp` — full regex flexibility
|
|
388
|
+
* - function — fully custom predicate
|
|
389
|
+
*
|
|
390
|
+
* Glob examples:
|
|
391
|
+
* "/" only the home route
|
|
392
|
+
* "/admin/X" /admin/foo but NOT /admin/foo/bar (X = single star)
|
|
393
|
+
* "/admin/XX" /admin and any descendant (XX = double star)
|
|
394
|
+
* "/blog/X/comments" /blog/x/comments but not deeper paths (X = single star)
|
|
395
|
+
*/
|
|
396
|
+
export declare type RoutePattern = string | RegExp | ((pathname: string) => boolean);
|
|
397
|
+
|
|
268
398
|
export declare interface ScreenShareStateHandle {
|
|
269
399
|
isEnabled: boolean;
|
|
270
400
|
error: string | null;
|
|
@@ -275,6 +405,15 @@ export declare interface ScreenShareStateHandle {
|
|
|
275
405
|
clearError: () => void;
|
|
276
406
|
}
|
|
277
407
|
|
|
408
|
+
/**
|
|
409
|
+
* Pure: should the widget render at this pathname?
|
|
410
|
+
*
|
|
411
|
+
* @param pathname current path, or undefined if not yet known
|
|
412
|
+
* @param showOn if set, restricts rendering to matching paths only
|
|
413
|
+
* @param hideOn if set, blocks rendering on matching paths (wins)
|
|
414
|
+
*/
|
|
415
|
+
export declare function shouldRenderAtPath(pathname: string | undefined, showOn: RoutePattern[] | undefined, hideOn: RoutePattern[] | undefined): boolean;
|
|
416
|
+
|
|
278
417
|
declare interface State {
|
|
279
418
|
hasError: boolean;
|
|
280
419
|
error: Error | null;
|
|
@@ -363,6 +502,15 @@ export declare function useMediaDevices(): MediaDevicesHandle;
|
|
|
363
502
|
|
|
364
503
|
export declare function useMicrophoneState(): MicrophoneStateHandle;
|
|
365
504
|
|
|
505
|
+
/**
|
|
506
|
+
* Returns the current pathname, reactive to SPA navigation.
|
|
507
|
+
* Pass `controlledPathname` to skip internal detection (recommended for
|
|
508
|
+
* Next.js App Router and React Router v6+ consumers).
|
|
509
|
+
*/
|
|
510
|
+
export declare function usePathname(controlledPathname?: string): string;
|
|
511
|
+
|
|
512
|
+
export declare function useRouteMatch(pathname: string | undefined, showOn: RoutePattern[] | undefined, hideOn: RoutePattern[] | undefined): boolean;
|
|
513
|
+
|
|
366
514
|
export declare function useScreenShareState(): ScreenShareStateHandle;
|
|
367
515
|
|
|
368
516
|
export declare function useTranscript(): TranscriptHandle;
|