@tavus/embed 0.19.0 → 0.19.1

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 CHANGED
@@ -1,24 +1,29 @@
1
1
  # @tavus/embed
2
2
 
3
- Tavus experience as an inline `<tavus-embed>` custom element. Drop a single tag into any page and you get a fully working Tavus deployment in a shadow DOM — no React, no build step required.
3
+ Drop a face-to-face Tavus PAL into any page with the `<tavus-embed>` custom element. The element renders Tavus Conversational Video Interface (CVI) inline in your layout, the complete experience: preview, start button, device check, the live call, captions, chat and the after-call screen. Tavus runs the conversation; your page needs no backend and no API key, only a deployment id.
4
4
 
5
- Create and configure a deployment — and grab the embed snippet — in the [Tavus PAL Maker](https://maker.tavus.io).
5
+ Create and configure a deployment, and copy the embed snippet, in the [Tavus PAL Maker](https://maker.tavus.io). Theme, copy, modality, call limits, bot protection and allowed origins are all deployment settings; the element picks them up on load.
6
+
7
+ - Documentation: [Embed](https://docs.tavus.io/sections/deployments/embed) and [Host communication](https://docs.tavus.io/sections/deployments/host-communication)
8
+ - Working examples: [tavus-examples](https://github.com/Tavus-Engineering/tavus-examples/tree/main/examples#readme) (see [Examples](#examples) below)
9
+ - Floating launcher instead of an inline surface: [`@tavus/widget`](https://www.npmjs.com/package/@tavus/widget)
6
10
 
7
11
  ## Install
8
12
 
9
13
  Serve the page over HTTPS: browsers only allow camera, microphone and WebRTC in a secure context. `http://localhost` counts as secure, so local development works. On a plain-http page the element shows its generic "PAL is unavailable" screen instead of starting, and the browser console names the HTTPS cause.
10
14
 
11
- ### CDN (recommended for static pages)
15
+ ### CDN (static pages, site builders)
12
16
 
13
17
  ```html
18
+ <div style="width: 720px; aspect-ratio: 16 / 9;">
19
+ <tavus-embed deployment-id="YOUR_DEPLOYMENT_ID"></tavus-embed>
20
+ </div>
14
21
  <script src="https://unpkg.com/@tavus/embed@latest"></script>
15
-
16
- <tavus-embed deployment-id="YOUR_DEPLOYMENT_ID"></tavus-embed>
17
22
  ```
18
23
 
19
- For a pinned version, use `https://unpkg.com/@tavus/embed@0.1.0`.
24
+ For a pinned version, use a versioned URL such as `https://unpkg.com/@tavus/embed@0.19.0`. On Webflow, Framer, Wix or Squarespace, paste the script tag into the site's custom code and the element into an HTML embed block, then publish.
20
25
 
21
- ### npm (bundler / framework apps)
26
+ ### npm (bundler and framework apps)
22
27
 
23
28
  ```bash
24
29
  npm install @tavus/embed
@@ -28,23 +33,32 @@ npm install @tavus/embed
28
33
  import "@tavus/embed";
29
34
  ```
30
35
 
31
- Importing the package registers the `<tavus-embed>` custom element as a side effect. After that you can use the tag anywhere in your app's markup — including JSX:
36
+ Importing the package registers the `<tavus-embed>` custom element as a side effect and ships JSX typings, so the tag type-checks in React:
32
37
 
33
38
  ```tsx
34
39
  <tavus-embed deployment-id="YOUR_DEPLOYMENT_ID" />
35
40
  ```
36
41
 
42
+ Keep the import static, even when you mount the element later from a button: a lazy `import("@tavus/embed")` makes Vite's dev server re-optimise dependencies mid-session, which can leave the page with two copies of React. In a server-rendered framework (Next.js, Remix, Nuxt, SvelteKit) the element is browser-only. Import it inside a client component (`"use client"` in Next.js) or after mount.
43
+
37
44
  ## Attributes
38
45
 
39
- | Attribute | Type | Description |
40
- | ----------------- | --------------------------- | ------------------------------------------------------------------------------- |
41
- | `deployment-id` | string | The Tavus deployment ID. Fetches configuration from `/v2/deployments/:id/init`. |
42
- | `override-config` | JSON | Optional JSON object that is deep-merged over the fetched config. |
43
- | `layout` | `"inline" \| "full-screen"` | Where the preview copy sits. Defaults to `inline`. See [Layout](#layout). |
46
+ | Attribute | Type | Description |
47
+ | ------------------------ | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
48
+ | `deployment-id` | string | The Tavus deployment id. The element fetches its configuration from `/v2/deployments/:id/init`. |
49
+ | `override-config` | JSON string | Deep-merged over the fetched configuration for page-specific copy or behaviour, for example `{"customization":{"show_haircheck":false}}`. |
50
+ | `layout` | `"inline" \| "full-screen"` | How the preview screen arranges its copy. Defaults to `inline`. See [Layout](#layout). |
51
+ | `expand-options` | JSON string | Lifts the card into a modal overlay for the conversation. See [Expanding into a modal](#expanding-into-a-modal). |
52
+ | `conversational-context` | string | Text the PAL knows during this conversation: who the visitor is, what the page is about. |
53
+ | `custom-greeting` | string | The PAL's first line. |
54
+ | `memory-stores` | string | Comma-separated memory tags, each a stable identifier for this visitor (a user id, not a display name), so the PAL remembers that visitor across conversations. One shared value would give every visitor the same memory. |
55
+ | `camera-on-start` | `"on" \| "off"` | Whether the visitor's camera is on when the call starts. Defaults to `on`. |
56
+
57
+ Attribute shapes and defaults are kept current in the [Embed reference](https://docs.tavus.io/sections/deployments/embed).
44
58
 
45
59
  ## Sizing
46
60
 
47
- `<tavus-embed>` sets `:host` to `width: 100%; height: 100%; max-height: 100vh; overflow: hidden`. Give it a parent with a definite size, or wrap it in a container with `aspect-ratio`.
61
+ `<tavus-embed>` sets `:host` to `width: 100%; height: 100%; max-height: 100vh; overflow: hidden`. It fills its parent, so give it a parent with a definite size, or wrap it in a container with `aspect-ratio`.
48
62
 
49
63
  ```html
50
64
  <div style="width: 720px; aspect-ratio: 16 / 9;">
@@ -52,9 +66,11 @@ Importing the package registers the `<tavus-embed>` custom element as a side eff
52
66
  </div>
53
67
  ```
54
68
 
69
+ Orientation is the page's call. Landscape (16:9) suits sections and cards on desktop pages; portrait (9:16) suits kiosks, phones and tall sidebars. Below `56.25rem` (900px) of container width the element switches to its compact portrait layout, and when the parent has no definite height it falls back to 16:9 above that width and 9:16 below. On phones give a landscape wrapper a 9:16 box with a media query. The element's type scale follows the root font size, so a larger root font gives larger controls, which matters on a kiosk screen.
70
+
55
71
  ## Layout
56
72
 
57
- `layout` only changes how the preview screen arranges its copy — sizing stays entirely yours (the element always fills its parent, in either mode).
73
+ `layout` only changes how the preview screen arranges its copy. Sizing stays entirely yours; the element always fills its parent, in either mode.
58
74
 
59
75
  - `inline` (default): the greeting and the start button share a bar along the bottom edge. Below a container width of `56.25rem` the greeting moves up to the top corner, since the bar has no room for both.
60
76
  - `full-screen`: the greeting always sits in the top-left corner and the start button is centered above the lower edge, clear of the replica's face. Meant for a section that gives the embed the whole viewport; the in-call fullscreen toggle is dropped, since the page is already the app.
@@ -65,6 +81,95 @@ Importing the package registers the `<tavus-embed>` custom element as a side eff
65
81
  </section>
66
82
  ```
67
83
 
84
+ ## Expanding into a modal
85
+
86
+ `expand-options` lifts the card out of the page into a modal overlay for the conversation. The overlay opens as soon as a start is underway, stays through the device check and the call, and returns the card inline when the call ends. Escape ends the conversation. The modal is a `<dialog>` inside the element's shadow root on the browser's top layer; the element itself stays where it is in the page, so the page owns no modal code and needs no scroll lock.
87
+
88
+ ```html
89
+ <tavus-embed
90
+ deployment-id="YOUR_DEPLOYMENT_ID"
91
+ expand-options='{"enabled": true, "aspect": "vertical", "max_height": 960}'
92
+ ></tavus-embed>
93
+ ```
94
+
95
+ | Key | Type | Default | Effect |
96
+ | --------------- | ---------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
97
+ | `enabled` | boolean | `false` | Expand the card for the conversation. |
98
+ | `aspect` | `"horizontal" \| "vertical"` | `"horizontal"` | 16:9 or 9:16. |
99
+ | `custom_aspect` | string \| number | | Any ratio, as `"4:3"`, `"16/9"` or a number (width ÷ height). Overrides `aspect`. |
100
+ | `max_width` | number (px) | 1280 for a landscape card (1600 on viewports 2560px and wider), none for a portrait one | Largest width the expanded card takes. |
101
+ | `max_height` | number (px) | 900 for a portrait card (1200 on viewports 2560px and wider), none for a landscape one | Largest height the expanded card takes. |
102
+ | `fullscreen` | boolean | `false` | Fill the viewport edge to edge. Overrides the ratio, the caps and the gutter. |
103
+
104
+ Values that do not parse are ignored, so a typo falls back to the defaults. The attribute is observed: setting it later updates the card, and disabling it during a call collapses the modal.
105
+
106
+ ## Talking to the element
107
+
108
+ The element dispatches events the page can listen to and installs methods the page can call. Everything below is documented in full, with payloads and types, in [Host communication](https://docs.tavus.io/sections/deployments/host-communication).
109
+
110
+ Events bubble from the element to `document`:
111
+
112
+ ```js
113
+ const el = document.querySelector("tavus-embed");
114
+ el.addEventListener("tavus:ready", (e) => {}); // { deploymentId } — methods are installed from here on
115
+ el.addEventListener("tavus:conversation-started", (e) => {}); // { conversationId }
116
+ el.addEventListener("tavus:conversation-ended", (e) => {}); // { conversationId }
117
+ el.addEventListener("tavus:error", (e) => {}); // { code, message }
118
+ el.addEventListener("tavus:tool-call", (e) => {}); // { name, arguments, tool_call_id?, seq?, turn_idx? }
119
+ el.addEventListener("tavus:protocol-message", (e) => {}); // every protocol event, e.g. conversation.utterance
120
+ ```
121
+
122
+ Also `tavus:conversation-created`, `tavus:state-change` and `tavus:mode-change`. `tavus:chat-message` and `tavus:message` are in the type definitions for compatibility and never fire.
123
+
124
+ Methods exist once `tavus:ready` has fired:
125
+
126
+ ```js
127
+ el.startConversation(); // same path as the visitor pressing Start; never rejects. Most failures arrive as tavus:error;
128
+ // the daily limit, a busy PAL and a bot check that cannot run arrive as tavus:mode-change with mode "unavailable"
129
+ await el.createConversation(); // create the room now so the next start joins without the wait
130
+ el.endConversation();
131
+ el.sendMessage({
132
+ event_type: "conversation.respond",
133
+ properties: { text: "Tell me about pricing" },
134
+ });
135
+ el.updateConfig({ customization: { style: { mode: "dark" } } });
136
+ el.destroy();
137
+ ```
138
+
139
+ Interactions you can send: `conversation.respond`, `conversation.echo`, `conversation.interrupt`, `conversation.append_llm_context`, `conversation.overwrite_llm_context` and `conversation.tool_result` (the reply to a `tavus:tool-call`).
140
+
141
+ In a bundled app, `TavusIntegration` wraps the same methods with typed event subscriptions. Create it after the element is in the DOM:
142
+
143
+ ```ts
144
+ import { TavusIntegration } from "@tavus/embed";
145
+
146
+ const tavus = new TavusIntegration("tavus-embed");
147
+ // tavus:ready fires once; if the element is already ready when this runs, start right away.
148
+ const el = document.querySelector("tavus-embed");
149
+ if (typeof el?.startConversation === "function") tavus.startConversation();
150
+ else tavus.on("tavus:ready", () => tavus.startConversation());
151
+ tavus.on("tavus:conversation-started", (e) => {
152
+ console.log(e.detail.conversationId);
153
+ // Messages are accepted only while the call is live; plain strings are wrapped as conversation.respond.
154
+ tavus.sendMessage("Tell me about pricing");
155
+ });
156
+ ```
157
+
158
+ ## Examples
159
+
160
+ Six complete pages in [tavus-examples](https://github.com/Tavus-Engineering/tavus-examples/tree/main/examples#readme), each with a screenshot and a recording of a full call:
161
+
162
+ | Example | Shows |
163
+ | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
164
+ | [embed-landing-page](https://github.com/Tavus-Engineering/tavus-examples/tree/main/examples/embed-landing-page) | The element in its own section of a marketing page. The simplest integration. |
165
+ | [embed-preview-to-modal](https://github.com/Tavus-Engineering/tavus-examples/tree/main/examples/embed-preview-to-modal) | A product hero whose agent card expands into a modal for the call (`expand-options`). |
166
+ | [embed-programmatic](https://github.com/Tavus-Engineering/tavus-examples/tree/main/examples/embed-programmatic) | The page's own button mounts the element and starts the call through `TavusIntegration`. |
167
+ | [embed-full-screen](https://github.com/Tavus-Engineering/tavus-examples/tree/main/examples/embed-full-screen) | A three-step flow where the call is the middle step on its own route with `layout="full-screen"`; the room is created during the intake step. |
168
+ | [embed-unattended-screen](https://github.com/Tavus-Engineering/tavus-examples/tree/main/examples/embed-unattended-screen) | An unattended screen (kiosk, lobby, trade-show stand): a portrait check-in totem that resets itself between visitors. |
169
+ | [embed-session-flow](https://github.com/Tavus-Engineering/tavus-examples/tree/main/examples/embed-session-flow) | Name step, call with a live transcript from protocol events, summary with a transcript download. |
170
+
171
+ Building with a coding agent (Cursor, Claude Code, Lovable, Replit)? Paste the [embed prompt](https://github.com/Tavus-Engineering/tavus-examples/blob/main/examples/embed-prompt.md). It asks what you want to build, explains what the element can do, and points the agent at these examples and the docs. The documentation index for agents is at [docs.tavus.io/llms.txt](https://docs.tavus.io/llms.txt).
172
+
68
173
  ## License
69
174
 
70
175
  MIT
package/dist/index.d.ts CHANGED
@@ -25,7 +25,8 @@ interface TavusEmbedAttributes {
25
25
  * JSON `ExpandOptions`. With `enabled: true` the card lifts out of the page
26
26
  * into a modal overlay while a start is underway and during the call, then
27
27
  * returns inline. `aspect`, `custom_aspect`, `max_width`, `max_height` and
28
- * `fullscreen` size the expanded card. See README "Embed".
28
+ * `fullscreen` size the expanded card. See the package README, "Expanding into a modal",
29
+ * or https://docs.tavus.io/sections/deployments/embed.
29
30
  */
30
31
  "expand-options"?: string;
31
32
  /** Preview/auth token forwarded to `/init` and `/start`. */