@yak-io/react 0.9.0 → 0.11.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 +101 -85
- package/dist/YakProvider.d.ts +8 -10
- package/dist/YakProvider.d.ts.map +1 -1
- package/dist/YakProvider.js +8 -9
- package/dist/YakWidget.d.ts.map +1 -1
- package/dist/YakWidget.js +3 -2
- package/dist/context.d.ts +7 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +2 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
# @yak-io/react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> 📚 **Full documentation:** https://docs.yak.io/docs/sdks/react
|
|
4
|
+
>
|
|
5
|
+
> 🤖 **For LLMs / AI agents:** https://docs.yak.io/llms.txt
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
React SDK for [Yak](https://docs.yak.io) — an embeddable AI assistant (text chat **and** push-to-talk voice) for web apps. Wrap your app in `YakProvider`, render `YakWidget` (or build your own trigger), and control everything with the `useYak()` hook.
|
|
8
|
+
|
|
9
|
+
**On Next.js, use [`@yak-io/nextjs`](https://docs.yak.io/docs/sdks/nextjs) instead** — it adds route scanning and server handler factories on top of this package.
|
|
6
10
|
|
|
7
11
|
```bash
|
|
8
12
|
pnpm add @yak-io/react
|
|
9
13
|
```
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
## Exports
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
| Export | Kind | Purpose |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| `YakProvider` | component | Sets up the chat + voice runtime. Wrap your app once. |
|
|
20
|
+
| `YakWidget` | component | The floating launcher pill. Render it inside `YakProvider`, or omit it and build your own trigger. |
|
|
21
|
+
| `useYak()` | hook | Imperative control of chat + voice, plus reactive state. |
|
|
22
|
+
| `useYakToolEvent(handler)` | hook | Run a callback after each tool call (e.g. cache invalidation). |
|
|
23
|
+
| `createYakToolset` / `createYakServerAdapter` | fn | Compose GraphQL/REST/tRPC/custom tool adapters into one `onToolCall` (re-exported from `@yak-io/javascript`). |
|
|
24
|
+
| `enableYakLogging` / `disableYakLogging` / `isYakLoggingEnabled` | fn | Toggle verbose SDK logging. |
|
|
25
|
+
| Types | — | `YakProviderProps`, `YakWidgetProps`, `YakContextValue`, plus core types re-exported from `@yak-io/javascript`. |
|
|
14
26
|
|
|
15
|
-
|
|
27
|
+
## Quickstart
|
|
16
28
|
|
|
17
29
|
```tsx
|
|
18
30
|
// src/App.tsx (or your root layout)
|
|
@@ -22,11 +34,14 @@ export default function App({ children }: { children: React.ReactNode }) {
|
|
|
22
34
|
return (
|
|
23
35
|
<YakProvider
|
|
24
36
|
appId={import.meta.env.VITE_YAK_APP_ID}
|
|
37
|
+
mode="both" // "chat" | "voice" | "both" — default "chat"
|
|
25
38
|
theme={{ position: "bottom-right", colorMode: "system" }}
|
|
39
|
+
// Routes + tools the assistant may use (usually your server endpoint).
|
|
26
40
|
getConfig={async () => {
|
|
27
41
|
const res = await fetch("/api/yak");
|
|
28
42
|
return res.json();
|
|
29
43
|
}}
|
|
44
|
+
// Execute a tool the assistant decides to call.
|
|
30
45
|
onToolCall={async (name, args) => {
|
|
31
46
|
const res = await fetch("/api/yak", {
|
|
32
47
|
method: "POST",
|
|
@@ -45,142 +60,143 @@ export default function App({ children }: { children: React.ReactNode }) {
|
|
|
45
60
|
}
|
|
46
61
|
```
|
|
47
62
|
|
|
48
|
-
|
|
63
|
+
## Programmatic control
|
|
64
|
+
|
|
65
|
+
`useYak()` works from any component inside `YakProvider`. To skip the floating pill entirely, just don't render `<YakWidget>` and wire your own buttons:
|
|
49
66
|
|
|
50
67
|
```tsx
|
|
51
68
|
import { useYak } from "@yak-io/react";
|
|
52
69
|
|
|
53
|
-
|
|
70
|
+
function HelpButton() {
|
|
54
71
|
const { open, openWithPrompt, isOpen } = useYak();
|
|
72
|
+
return (
|
|
73
|
+
<>
|
|
74
|
+
<button onClick={open}>Open chat</button>
|
|
75
|
+
<button onClick={() => openWithPrompt("How do I get started?")}>Get help</button>
|
|
76
|
+
{isOpen && <span>Chat is open</span>}
|
|
77
|
+
</>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Voice
|
|
83
|
+
|
|
84
|
+
Set `mode="voice"` or `mode="both"` on the provider, then drive the session with the voice methods. `voiceStart()` must run from a user gesture (browser mic requirement).
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { useYak } from "@yak-io/react";
|
|
55
88
|
|
|
89
|
+
function VoiceButton() {
|
|
90
|
+
const { voiceToggle, voiceState, voiceIsActive, voiceLoading } = useYak();
|
|
56
91
|
return (
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Get Help
|
|
61
|
-
</button>
|
|
62
|
-
{isOpen && <p>Chat is open</p>}
|
|
63
|
-
</div>
|
|
92
|
+
<button onClick={voiceToggle} disabled={voiceLoading}>
|
|
93
|
+
{voiceIsActive ? `Stop (${voiceState})` : "Start voice"}
|
|
94
|
+
</button>
|
|
64
95
|
);
|
|
65
96
|
}
|
|
66
97
|
```
|
|
67
98
|
|
|
68
|
-
|
|
99
|
+
## Tool events
|
|
100
|
+
|
|
101
|
+
Re-sync your UI when the assistant changes data:
|
|
69
102
|
|
|
70
103
|
```tsx
|
|
71
104
|
import { useYakToolEvent } from "@yak-io/react";
|
|
72
105
|
|
|
73
106
|
function TasksPage() {
|
|
74
|
-
const [tasks, setTasks] = useState([]);
|
|
75
|
-
|
|
76
|
-
// Re-fetch when the chatbot modifies tasks
|
|
77
107
|
useYakToolEvent((event) => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
108
|
+
// { name, args, ok, result?, error? }
|
|
109
|
+
if (event.ok && event.name.startsWith("tasks.")) refetchTasks();
|
|
81
110
|
});
|
|
82
|
-
|
|
83
111
|
// ...
|
|
84
112
|
}
|
|
85
113
|
```
|
|
86
114
|
|
|
87
|
-
## API
|
|
115
|
+
## API reference
|
|
88
116
|
|
|
89
|
-
###
|
|
117
|
+
### `<YakProvider>`
|
|
90
118
|
|
|
91
|
-
|
|
119
|
+
| Prop | Type | Default | Description |
|
|
120
|
+
| --- | --- | --- | --- |
|
|
121
|
+
| `appId` | `string` | — | Your Yak app ID (required). |
|
|
122
|
+
| `children` | `ReactNode` | — | Your app (required). |
|
|
123
|
+
| `mode` | `"chat" \| "voice" \| "both"` | `"chat"` | Which surfaces are exposed. |
|
|
124
|
+
| `getConfig` | `ChatConfigProvider` | — | Async provider of routes + tools. Called on open / voice start. |
|
|
125
|
+
| `onToolCall` | `ToolCallHandler` | — | Executes a tool the assistant calls. || `theme` | `Theme` | — | Position, color mode, and colors. |
|
|
126
|
+
| `onRedirect` | `(path: string) => void` | `window.location.assign` | Navigation handler. |
|
|
127
|
+
| `disableRestartButton` | `boolean` | `false` | Hide the restart-session button. |
|
|
128
|
+
| `trigger` | `boolean \| TriggerButtonConfig` | `false` | Render the provider's built-in pill. Leave `false` and use `<YakWidget>` instead. |
|
|
129
|
+
| `user` | `UserIdentity` | — | Signed end-user identity for conversation persistence. See [end-user identity](https://docs.yak.io/docs/customization/end-user-identity). |
|
|
92
130
|
|
|
93
|
-
|
|
131
|
+
### `<YakWidget>`
|
|
94
132
|
|
|
95
|
-
|
|
96
|
-
|------|------|----------|-------------|
|
|
97
|
-
| `appId` | `string` | ✅ | Your Yak app ID |
|
|
98
|
-
| `children` | `ReactNode` | ✅ | Your app content |
|
|
99
|
-
| `getConfig` | `ChatConfigProvider` | — | Async function returning routes + tools config. Called when the widget opens. |
|
|
100
|
-
| `onToolCall` | `ToolCallHandler` | — | Handle tool calls from the assistant |
|
|
101
|
-
| `onGraphQLSchemaCall` | `GraphQLSchemaHandler` | — | Handle GraphQL schema tool calls |
|
|
102
|
-
| `onRESTSchemaCall` | `RESTSchemaHandler` | — | Handle REST/OpenAPI schema tool calls |
|
|
103
|
-
| `theme` | `Theme` | — | Widget theme (position, colorMode, colors) |
|
|
104
|
-
| `onRedirect` | `(path: string) => void` | — | Custom navigation handler (defaults to `window.location.assign`) |
|
|
105
|
-
| `disableRestartButton` | `boolean` | — | Hide the restart session button |
|
|
106
|
-
| `trigger` | `boolean \| TriggerButtonConfig` | — | Built-in trigger button config (`false` by default — use `<YakWidget>` instead) |
|
|
133
|
+
The floating launcher pill. Shows a chat icon, a voice icon, or both, based on `mode`.
|
|
107
134
|
|
|
108
|
-
|
|
135
|
+
| Prop | Type | Default | Description |
|
|
136
|
+
| --- | --- | --- | --- |
|
|
137
|
+
| `mode` | `"chat" \| "voice" \| "both"` | inherits provider | Override which icons appear. |
|
|
138
|
+
| `lightButton` | `{ background?, color?, border? }` | — | Pill colors in light mode. |
|
|
139
|
+
| `darkButton` | `{ background?, color?, border? }` | — | Pill colors in dark mode. |
|
|
109
140
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
**Props:**
|
|
113
|
-
|
|
114
|
-
| Prop | Type | Description |
|
|
115
|
-
|------|------|-------------|
|
|
116
|
-
| `triggerLabel` | `string` | Button label (default: `"Ask with AI"`) |
|
|
117
|
-
| `position` | `WidgetPosition` | Button position (default: `"bottom-right"`) |
|
|
118
|
-
| `colorMode` | `"light" \| "dark" \| "system"` | Color mode override |
|
|
119
|
-
| `lightButton` | `{ background?, color?, border? }` | Custom light mode button colors |
|
|
120
|
-
| `darkButton` | `{ background?, color?, border? }` | Custom dark mode button colors |
|
|
141
|
+
> Position and color mode come from the provider's `theme` (`theme.position`, `theme.colorMode`) — not from `YakWidget` props.
|
|
121
142
|
|
|
122
143
|
### `useYak()`
|
|
123
144
|
|
|
124
|
-
|
|
145
|
+
Returns `YakContextValue`. Throws if used outside `YakProvider`.
|
|
125
146
|
|
|
126
147
|
```ts
|
|
127
148
|
const {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
149
|
+
// chat
|
|
150
|
+
isOpen, // boolean
|
|
151
|
+
isReady, // boolean — iframe ready to receive messages
|
|
152
|
+
chatLoading, // boolean — isOpen && !isReady (show a loading spinner)
|
|
153
|
+
open, // () => void
|
|
154
|
+
close, // () => void
|
|
155
|
+
openWithPrompt, // (prompt: string) => void
|
|
156
|
+
// voice
|
|
157
|
+
voiceState, // "idle" | "connecting" | "listening" | "thinking" | "speaking" | "error"
|
|
158
|
+
voiceMachine, // { state, errorMessage? }
|
|
159
|
+
voiceIsActive, // boolean — connecting/listening/thinking/speaking
|
|
160
|
+
voiceLoading, // boolean — voiceState === "connecting"
|
|
161
|
+
voiceErrorMessage, // string | undefined
|
|
162
|
+
voiceStart, // () => Promise<void>
|
|
163
|
+
voiceStop, // () => Promise<void>
|
|
164
|
+
voiceToggle, // () => Promise<void>
|
|
165
|
+
// misc
|
|
166
|
+
mode, // "chat" | "voice" | "both"
|
|
133
167
|
subscribeToToolEvents, // (handler) => () => void
|
|
134
168
|
} = useYak();
|
|
135
169
|
```
|
|
136
170
|
|
|
137
|
-
Throws if called outside `YakProvider`.
|
|
138
|
-
|
|
139
|
-
### `useYakToolEvent(handler)`
|
|
140
|
-
|
|
141
|
-
Subscribe to tool call completion events. Automatically unsubscribes on unmount. Useful for cache invalidation when the chatbot modifies data.
|
|
142
|
-
|
|
143
|
-
```ts
|
|
144
|
-
useYakToolEvent((event) => {
|
|
145
|
-
// event.name — the tool name called ("tasks.list")
|
|
146
|
-
// event.args — arguments passed to the tool
|
|
147
|
-
// event.ok — whether the call succeeded
|
|
148
|
-
// event.result — the result (if ok)
|
|
149
|
-
// event.error — error message (if not ok)
|
|
150
|
-
});
|
|
151
|
-
```
|
|
152
|
-
|
|
153
171
|
## Logging
|
|
154
172
|
|
|
155
173
|
```ts
|
|
156
174
|
import { enableYakLogging, disableYakLogging, isYakLoggingEnabled } from "@yak-io/react";
|
|
157
175
|
|
|
158
|
-
enableYakLogging();
|
|
159
|
-
disableYakLogging(); // Disable SDK logs
|
|
160
|
-
isYakLoggingEnabled(); // → boolean
|
|
176
|
+
enableYakLogging(); // verbose SDK logs
|
|
161
177
|
```
|
|
162
178
|
|
|
163
179
|
## Types
|
|
164
180
|
|
|
165
|
-
All key types are re-exported for convenience:
|
|
166
|
-
|
|
167
181
|
```ts
|
|
168
182
|
import type {
|
|
183
|
+
YakProviderProps,
|
|
184
|
+
YakWidgetProps,
|
|
185
|
+
YakContextValue,
|
|
169
186
|
ChatConfigProvider,
|
|
170
187
|
ToolCallHandler,
|
|
171
188
|
ToolCallEvent,
|
|
172
|
-
|
|
173
|
-
|
|
189
|
+
ToolAdapter,
|
|
190
|
+
YakToolset,
|
|
191
|
+
YakServerAdapterConfig,
|
|
174
192
|
Theme,
|
|
175
|
-
|
|
176
|
-
TriggerButtonConfig,
|
|
193
|
+
WidgetMode,
|
|
177
194
|
WidgetPosition,
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
OpenAPISchemaSource,
|
|
195
|
+
VoiceState,
|
|
196
|
+
VoiceMachine,
|
|
181
197
|
} from "@yak-io/react";
|
|
182
198
|
```
|
|
183
199
|
|
|
184
200
|
## License
|
|
185
201
|
|
|
186
|
-
Proprietary — see LICENSE
|
|
202
|
+
Proprietary — see [LICENSE](./LICENSE).
|
package/dist/YakProvider.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ChatConfigProvider, type
|
|
1
|
+
import { type ChatConfigProvider, type Theme, type ToolCallHandler, type TriggerButtonConfig, type UserIdentity, type WidgetMode } from "@yak-io/javascript";
|
|
2
2
|
import type React from "react";
|
|
3
3
|
/**
|
|
4
4
|
* Props for YakProvider
|
|
@@ -6,6 +6,12 @@ import type React from "react";
|
|
|
6
6
|
export type YakProviderProps = {
|
|
7
7
|
/** App identifier in the yak SaaS */
|
|
8
8
|
appId: string;
|
|
9
|
+
/**
|
|
10
|
+
* Override the origin the chat/voice runtime connects to. Defaults to
|
|
11
|
+
* `https://chat.yak.io`. Read once when the provider mounts; most integrators
|
|
12
|
+
* never set this.
|
|
13
|
+
*/
|
|
14
|
+
origin?: string;
|
|
9
15
|
/**
|
|
10
16
|
* Which experiences this widget exposes.
|
|
11
17
|
* "chat" — chat only (iframe).
|
|
@@ -25,14 +31,6 @@ export type YakProviderProps = {
|
|
|
25
31
|
* The consuming platform decides how to execute (browser, server fetch, etc.)
|
|
26
32
|
*/
|
|
27
33
|
onToolCall?: ToolCallHandler;
|
|
28
|
-
/**
|
|
29
|
-
* Handler for GraphQL schema tool calls.
|
|
30
|
-
*/
|
|
31
|
-
onGraphQLSchemaCall?: GraphQLSchemaHandler;
|
|
32
|
-
/**
|
|
33
|
-
* Handler for REST/OpenAPI schema tool calls.
|
|
34
|
-
*/
|
|
35
|
-
onRESTSchemaCall?: RESTSchemaHandler;
|
|
36
34
|
/** Optional theme configuration */
|
|
37
35
|
theme?: Theme;
|
|
38
36
|
/** Optional redirect handler (defaults to window.location.assign) */
|
|
@@ -62,5 +60,5 @@ export type YakProviderProps = {
|
|
|
62
60
|
* (panel, iframe, optional trigger) is delegated to YakEmbed. Consumers
|
|
63
61
|
* access both surfaces via `useYak()`.
|
|
64
62
|
*/
|
|
65
|
-
export declare function YakProvider({ appId, mode, getConfig, onToolCall,
|
|
63
|
+
export declare function YakProvider({ appId, origin, mode, getConfig, onToolCall, theme, onRedirect, disableRestartButton, trigger, user, children, }: YakProviderProps): React.JSX.Element;
|
|
66
64
|
//# sourceMappingURL=YakProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YakProvider.d.ts","sourceRoot":"","sources":["../src/YakProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,kBAAkB,
|
|
1
|
+
{"version":3,"file":"YakProvider.d.ts","sourceRoot":"","sources":["../src/YakProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,kBAAkB,EAGvB,KAAK,KAAK,EAEV,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EAEjB,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,mCAAmC;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,qEAAqE;IACrE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,uDAAuD;IACvD,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;IACxC;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,0BAA0B;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,MAAM,EACN,IAAa,EACb,SAAS,EACT,UAAU,EACV,KAAK,EACL,UAAU,EACV,oBAAoB,EACpB,OAAe,EACf,IAAI,EACJ,QAAQ,GACT,EAAE,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA4MtC"}
|
package/dist/YakProvider.js
CHANGED
|
@@ -8,7 +8,7 @@ import { YakContext } from "./context.js";
|
|
|
8
8
|
* (panel, iframe, optional trigger) is delegated to YakEmbed. Consumers
|
|
9
9
|
* access both surfaces via `useYak()`.
|
|
10
10
|
*/
|
|
11
|
-
export function YakProvider({ appId, mode = "chat", getConfig, onToolCall,
|
|
11
|
+
export function YakProvider({ appId, origin, mode = "chat", getConfig, onToolCall, theme, onRedirect, disableRestartButton, trigger = false, user, children, }) {
|
|
12
12
|
const [isOpen, setIsOpen] = useState(false);
|
|
13
13
|
const [isReady, setIsReady] = useState(false);
|
|
14
14
|
const [voiceMachine, setVoiceMachine] = useState(INITIAL_VOICE_MACHINE);
|
|
@@ -45,13 +45,12 @@ export function YakProvider({ appId, mode = "chat", getConfig, onToolCall, onGra
|
|
|
45
45
|
if (!embedRef.current) {
|
|
46
46
|
embedRef.current = new YakEmbed({
|
|
47
47
|
appId,
|
|
48
|
+
origin,
|
|
48
49
|
mode,
|
|
49
50
|
theme,
|
|
50
51
|
trigger,
|
|
51
52
|
getConfig,
|
|
52
53
|
onToolCall,
|
|
53
|
-
onGraphQLSchemaCall,
|
|
54
|
-
onRESTSchemaCall,
|
|
55
54
|
onRedirect: resolvedRedirect,
|
|
56
55
|
options: { disableRestartButton },
|
|
57
56
|
onToolCallComplete: handleToolCallComplete,
|
|
@@ -79,8 +78,6 @@ export function YakProvider({ appId, mode = "chat", getConfig, onToolCall, onGra
|
|
|
79
78
|
embed.getClient().updateConfig({
|
|
80
79
|
appId,
|
|
81
80
|
onToolCall,
|
|
82
|
-
onGraphQLSchemaCall,
|
|
83
|
-
onRESTSchemaCall,
|
|
84
81
|
theme,
|
|
85
82
|
onRedirect: resolvedRedirect,
|
|
86
83
|
options: { disableRestartButton },
|
|
@@ -91,16 +88,12 @@ export function YakProvider({ appId, mode = "chat", getConfig, onToolCall, onGra
|
|
|
91
88
|
appId,
|
|
92
89
|
getConfig,
|
|
93
90
|
onToolCall,
|
|
94
|
-
onGraphQLSchemaCall,
|
|
95
|
-
onRESTSchemaCall,
|
|
96
91
|
onRedirect: resolvedRedirect,
|
|
97
92
|
});
|
|
98
93
|
}, [
|
|
99
94
|
appId,
|
|
100
95
|
getConfig,
|
|
101
96
|
onToolCall,
|
|
102
|
-
onGraphQLSchemaCall,
|
|
103
|
-
onRESTSchemaCall,
|
|
104
97
|
theme,
|
|
105
98
|
resolvedRedirect,
|
|
106
99
|
disableRestartButton,
|
|
@@ -158,10 +151,13 @@ export function YakProvider({ appId, mode = "chat", getConfig, onToolCall, onGra
|
|
|
158
151
|
const getIframeOrigin = useCallback(() => embed.getClient().getIframeOrigin(), [embed]);
|
|
159
152
|
const voiceState = voiceMachine.state;
|
|
160
153
|
const voiceIsActive = voiceState !== "idle" && voiceState !== "error";
|
|
154
|
+
const chatLoading = isOpen && !isReady;
|
|
155
|
+
const voiceLoading = voiceState === "connecting";
|
|
161
156
|
const contextValue = useMemo(() => ({
|
|
162
157
|
mode,
|
|
163
158
|
isOpen,
|
|
164
159
|
isReady,
|
|
160
|
+
chatLoading,
|
|
165
161
|
open,
|
|
166
162
|
close,
|
|
167
163
|
openWithPrompt,
|
|
@@ -170,6 +166,7 @@ export function YakProvider({ appId, mode = "chat", getConfig, onToolCall, onGra
|
|
|
170
166
|
voiceState,
|
|
171
167
|
voiceErrorMessage: voiceMachine.errorMessage,
|
|
172
168
|
voiceIsActive,
|
|
169
|
+
voiceLoading,
|
|
173
170
|
voiceStart,
|
|
174
171
|
voiceStop,
|
|
175
172
|
voiceToggle,
|
|
@@ -179,6 +176,7 @@ export function YakProvider({ appId, mode = "chat", getConfig, onToolCall, onGra
|
|
|
179
176
|
mode,
|
|
180
177
|
isOpen,
|
|
181
178
|
isReady,
|
|
179
|
+
chatLoading,
|
|
182
180
|
open,
|
|
183
181
|
close,
|
|
184
182
|
openWithPrompt,
|
|
@@ -186,6 +184,7 @@ export function YakProvider({ appId, mode = "chat", getConfig, onToolCall, onGra
|
|
|
186
184
|
voiceMachine,
|
|
187
185
|
voiceState,
|
|
188
186
|
voiceIsActive,
|
|
187
|
+
voiceLoading,
|
|
189
188
|
voiceStart,
|
|
190
189
|
voiceStop,
|
|
191
190
|
voiceToggle,
|
package/dist/YakWidget.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YakWidget.d.ts","sourceRoot":"","sources":["../src/YakWidget.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,2CAA2C;IAC3C,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,0CAA0C;IAC1C,WAAW,CAAC,EAAE;QACZ,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,yCAAyC;IACzC,UAAU,CAAC,EAAE;QACX,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AAsGF;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,WAAW,EACX,UAAU,GACX,GAAE,cAAmB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"YakWidget.d.ts","sourceRoot":"","sources":["../src/YakWidget.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,2CAA2C;IAC3C,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,0CAA0C;IAC1C,WAAW,CAAC,EAAE;QACZ,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,yCAAyC;IACzC,UAAU,CAAC,EAAE;QACX,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AAsGF;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,WAAW,EACX,UAAU,GACX,GAAE,cAAmB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAmEzC"}
|
package/dist/YakWidget.js
CHANGED
|
@@ -68,8 +68,9 @@ export function YakWidget({ mode, lightButton, darkButton, } = {}) {
|
|
|
68
68
|
const logoUrl = `${ctx.getIframeOrigin()}/logo.svg`;
|
|
69
69
|
const showChat = resolvedMode === "chat" || resolvedMode === "both";
|
|
70
70
|
const showVoice = resolvedMode === "voice" || resolvedMode === "both";
|
|
71
|
-
|
|
72
|
-
const
|
|
71
|
+
// Consume the shipped loading flags rather than re-deriving them here.
|
|
72
|
+
const chatLoading = ctx.chatLoading;
|
|
73
|
+
const voiceConnecting = ctx.voiceLoading;
|
|
73
74
|
const hasLightCustom = lightButton?.background || lightButton?.color || lightButton?.border;
|
|
74
75
|
const hasDarkCustom = darkButton?.background || darkButton?.color || darkButton?.border;
|
|
75
76
|
const buttonStyle = buildButtonStyle(lightButton, darkButton);
|
package/dist/context.d.ts
CHANGED
|
@@ -23,6 +23,11 @@ export type YakContextValue = {
|
|
|
23
23
|
isOpen: boolean;
|
|
24
24
|
/** Whether the iframe is ready to receive messages */
|
|
25
25
|
isReady: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Whether the chat is opening but not yet interactive (`isOpen && !isReady`).
|
|
28
|
+
* Drive a custom loading state off this instead of re-deriving it.
|
|
29
|
+
*/
|
|
30
|
+
chatLoading: boolean;
|
|
26
31
|
/** Open the chat widget */
|
|
27
32
|
open: () => void;
|
|
28
33
|
/** Close the chat widget */
|
|
@@ -39,6 +44,8 @@ export type YakContextValue = {
|
|
|
39
44
|
voiceErrorMessage: string | undefined;
|
|
40
45
|
/** Whether a voice session is currently live (connecting/listening/thinking/speaking). */
|
|
41
46
|
voiceIsActive: boolean;
|
|
47
|
+
/** Whether the voice session is still connecting (`voiceState === "connecting"`). */
|
|
48
|
+
voiceLoading: boolean;
|
|
42
49
|
/** Start a voice session. Must be invoked from a user gesture. */
|
|
43
50
|
voiceStart: () => Promise<void>;
|
|
44
51
|
/** Stop the current voice session. */
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,KAAK,EACL,aAAa,EACb,YAAY,EACZ,UAAU,EACV,UAAU,EACX,MAAM,oBAAoB,CAAC;AAG5B;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,2DAA2D;IAC3D,IAAI,EAAE,UAAU,CAAC;IAGjB,gDAAgD;IAChD,MAAM,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;IACjB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,yDAAyD;IACzD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,+CAA+C;IAC/C,qBAAqB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,MAAM,IAAI,CAAC;IAGrE,yEAAyE;IACzE,YAAY,EAAE,YAAY,CAAC;IAC3B,yCAAyC;IACzC,UAAU,EAAE,UAAU,CAAC;IACvB,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,0FAA0F;IAC1F,aAAa,EAAE,OAAO,CAAC;IACvB,kEAAkE;IAClE,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,sCAAsC;IACtC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,mDAAmD;IACnD,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,eAAe,GAAG;IACtD,4DAA4D;IAC5D,eAAe,EAAE,MAAM,MAAM,CAAC;IAC9B,iFAAiF;IACjF,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,UAAU,yDAAsD,CAAC;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,IAAI,eAAe,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,KAAK,EACL,aAAa,EACb,YAAY,EACZ,UAAU,EACV,UAAU,EACX,MAAM,oBAAoB,CAAC;AAG5B;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,2DAA2D;IAC3D,IAAI,EAAE,UAAU,CAAC;IAGjB,gDAAgD;IAChD,MAAM,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,yDAAyD;IACzD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,+CAA+C;IAC/C,qBAAqB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,MAAM,IAAI,CAAC;IAGrE,yEAAyE;IACzE,YAAY,EAAE,YAAY,CAAC;IAC3B,yCAAyC;IACzC,UAAU,EAAE,UAAU,CAAC;IACvB,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,0FAA0F;IAC1F,aAAa,EAAE,OAAO,CAAC;IACvB,qFAAqF;IACrF,YAAY,EAAE,OAAO,CAAC;IACtB,kEAAkE;IAClE,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,sCAAsC;IACtC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,mDAAmD;IACnD,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,eAAe,GAAG;IACtD,4DAA4D;IAC5D,eAAe,EAAE,MAAM,MAAM,CAAC;IAC9B,iFAAiF;IACjF,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,UAAU,yDAAsD,CAAC;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,IAAI,eAAe,CAuBxC;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,uBAAuB,CAMxD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAkBnE"}
|
package/dist/context.js
CHANGED
|
@@ -28,6 +28,7 @@ export function useYak() {
|
|
|
28
28
|
mode: context.mode,
|
|
29
29
|
isOpen: context.isOpen,
|
|
30
30
|
isReady: context.isReady,
|
|
31
|
+
chatLoading: context.chatLoading,
|
|
31
32
|
open: context.open,
|
|
32
33
|
close: context.close,
|
|
33
34
|
openWithPrompt: context.openWithPrompt,
|
|
@@ -36,6 +37,7 @@ export function useYak() {
|
|
|
36
37
|
voiceState: context.voiceState,
|
|
37
38
|
voiceErrorMessage: context.voiceErrorMessage,
|
|
38
39
|
voiceIsActive: context.voiceIsActive,
|
|
40
|
+
voiceLoading: context.voiceLoading,
|
|
39
41
|
voiceStart: context.voiceStart,
|
|
40
42
|
voiceStop: context.voiceStop,
|
|
41
43
|
voiceToggle: context.voiceToggle,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export type { ChatConfigProvider, GraphQLRequest,
|
|
2
|
-
export { disableYakLogging, enableYakLogging, isYakLoggingEnabled } from "@yak-io/javascript";
|
|
1
|
+
export type { ChatConfigProvider, GraphQLRequest, RESTRequest, Theme, ThemeColors, ToolAdapter, ToolCallEvent, ToolCallHandler, TriggerButtonConfig, VoiceMachine, VoiceState, WidgetMode, WidgetPosition, YakServerAdapterConfig, YakToolset, } from "@yak-io/javascript";
|
|
2
|
+
export { createYakServerAdapter, createYakToolset, disableYakLogging, enableYakLogging, isYakLoggingEnabled, } from "@yak-io/javascript";
|
|
3
3
|
export type { ToolCallEventHandler, YakConfig, YakContextValue } from "./context.js";
|
|
4
4
|
export { useYak, useYakToolEvent } from "./context.js";
|
|
5
5
|
export type { YakProviderProps } from "./YakProvider.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,WAAW,EACX,KAAK,EACL,WAAW,EACX,WAAW,EACX,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,UAAU,GACX,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAErF,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
// Re-export useful types and constants from @yak-io/javascript for consumers
|
|
3
|
-
export { disableYakLogging, enableYakLogging, isYakLoggingEnabled } from "@yak-io/javascript";
|
|
3
|
+
export { createYakServerAdapter, createYakToolset, disableYakLogging, enableYakLogging, isYakLoggingEnabled, } from "@yak-io/javascript";
|
|
4
4
|
// Public API - only export what consumers need
|
|
5
5
|
export { useYak, useYakToolEvent } from "./context.js";
|
|
6
6
|
export { YakProvider } from "./YakProvider.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yak-io/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "React SDK for embedding yak chatbot",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"node": ">=18"
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
|
+
"README.md",
|
|
28
29
|
"dist",
|
|
29
30
|
"LICENSE"
|
|
30
31
|
],
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
"./package.json": "./package.json"
|
|
42
43
|
},
|
|
43
44
|
"dependencies": {
|
|
44
|
-
"@yak-io/javascript": "0.
|
|
45
|
+
"@yak-io/javascript": "0.10.0"
|
|
45
46
|
},
|
|
46
47
|
"peerDependencies": {
|
|
47
48
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -59,6 +60,7 @@
|
|
|
59
60
|
"typescript": "^5.3.0",
|
|
60
61
|
"@repo/typescript-config": "0.0.0"
|
|
61
62
|
},
|
|
63
|
+
"homepage": "https://docs.yak.io/docs/sdks/react",
|
|
62
64
|
"scripts": {
|
|
63
65
|
"build": "tsc",
|
|
64
66
|
"check-types": "tsc --noEmit",
|