@yak-io/vue 0.2.0 β†’ 0.4.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 CHANGED
@@ -1,25 +1,40 @@
1
1
  # @yak-io/vue
2
2
 
3
- Vue 3 integration for the Yak embeddable chat widget. Uses Vue's Composition API with reactive refs.
3
+ > πŸ“š **Full documentation:** https://docs.yak.io/docs/sdks/vue
4
+ >
5
+ > πŸ€– **For LLMs / AI agents:** https://docs.yak.io/llms.txt
4
6
 
5
- ## Installation
7
+ Vue 3 SDK for [Yak](https://docs.yak.io) β€” an embeddable AI assistant (text chat **and** push-to-talk voice) for web apps. Call `createYakProvider` once in your root component; reactive state is exposed as Vue refs and shared with descendants via `provide`/`inject`.
6
8
 
7
9
  ```bash
8
10
  pnpm add @yak-io/vue
9
11
  ```
10
12
 
11
- ## Quickstart
13
+ ## Exports
12
14
 
13
- ### 1. Initialize in your root component
15
+ | Export | Kind | Purpose |
16
+ | --- | --- | --- |
17
+ | `createYakProvider(options)` | fn | Initialize the widget in your root component. Returns a `YakApi`. Auto-mounts/unmounts. |
18
+ | `useYak()` | fn | Inject the `YakApi` in any descendant component. |
19
+ | `useYakToolEvent(handler)` | fn | Run a callback after each tool call (auto-unsubscribes on unmount). |
20
+ | `enableYakLogging` / `disableYakLogging` / `isYakLoggingEnabled` | fn | Toggle verbose SDK logging. |
21
+ | Types | β€” | `YakProviderOptions`, `YakApi`, `ToolCallEventHandler`, plus core types from `@yak-io/javascript`. |
14
22
 
15
- ```ts
16
- // App.vue <script setup>
23
+ ## Quickstart
24
+
25
+ ```vue
26
+ <!-- App.vue -->
27
+ <script setup lang="ts">
28
+ import { useRouter } from "vue-router";
17
29
  import { createYakProvider } from "@yak-io/vue";
18
30
 
31
+ const router = useRouter();
32
+
19
33
  createYakProvider({
20
34
  appId: import.meta.env.VITE_YAK_APP_ID,
35
+ mode: "both", // "chat" | "voice" | "both" β€” default "chat"
36
+ trigger: true, // show the floating launcher pill
21
37
  theme: { position: "bottom-right", colorMode: "system" },
22
- trigger: { label: "Ask with AI" },
23
38
  getConfig: async () => {
24
39
  const res = await fetch("/api/yak");
25
40
  return res.json();
@@ -34,100 +49,110 @@ createYakProvider({
34
49
  if (!data.ok) throw new Error(data.error);
35
50
  return data.result;
36
51
  },
37
- onRedirect: (path) => {
38
- router.push(path);
39
- },
52
+ onRedirect: (path) => router.push(path),
40
53
  });
54
+ </script>
55
+
56
+ <template>
57
+ <RouterView />
58
+ </template>
41
59
  ```
42
60
 
43
- `createYakProvider` calls `onMounted` and `onUnmounted` internally β€” no manual lifecycle management needed.
61
+ `createYakProvider` registers `onMounted`/`onUnmounted` for you β€” no manual lifecycle needed.
44
62
 
45
- ### 2. Use in descendant components
63
+ ## Programmatic control
46
64
 
47
- ```ts
48
- // MyComponent.vue <script setup>
65
+ ```vue
66
+ <script setup lang="ts">
49
67
  import { useYak } from "@yak-io/vue";
50
68
 
51
- const { open, openWithPrompt, isOpen, isReady } = useYak();
69
+ const { open, openWithPrompt, isOpen } = useYak();
70
+ </script>
71
+
72
+ <template>
73
+ <button @click="open">Open chat</button>
74
+ <button @click="openWithPrompt('How do I get started?')">Get help</button>
75
+ <span v-if="isOpen">Chat is open</span>
76
+ </template>
52
77
  ```
53
78
 
54
- `isOpen` and `isReady` are `readonly` Vue refs β€” use them like any other ref:
79
+ `isOpen`/`isReady` are `readonly` refs β€” use them directly in templates.
80
+
81
+ ## Voice
82
+
83
+ Set `mode: "voice"` or `mode: "both"`, then drive the session. `voiceStart()` must run from a user gesture (browser mic requirement).
84
+
85
+ ```vue
86
+ <script setup lang="ts">
87
+ import { useYak } from "@yak-io/vue";
88
+
89
+ const { voiceToggle, voiceLoading, voiceMachine } = useYak();
90
+ </script>
55
91
 
56
- ```html
57
92
  <template>
58
- <div>
59
- <button @click="open">Open Chat</button>
60
- <p v-if="isOpen">Chat is open</p>
61
- <p v-if="!isReady && isOpen">Loading…</p>
62
- </div>
93
+ <button @click="voiceToggle" :disabled="voiceLoading">
94
+ {{ voiceMachine.state === "idle" ? "Start voice" : `Stop (${voiceMachine.state})` }}
95
+ </button>
63
96
  </template>
64
97
  ```
65
98
 
66
- ### 3. Subscribe to tool events
99
+ ## Tool events
67
100
 
68
101
  ```ts
69
102
  import { useYakToolEvent } from "@yak-io/vue";
70
103
 
71
104
  useYakToolEvent((event) => {
72
- if (event.ok && event.name.startsWith("tasks.")) {
73
- refreshTasks();
74
- }
105
+ // { name, args, ok, result?, error? }
106
+ if (event.ok && event.name.startsWith("tasks.")) refreshTasks();
75
107
  });
76
108
  ```
77
109
 
78
- Automatically unsubscribes when the component unmounts.
79
-
80
- ## API Reference
110
+ ## API reference
81
111
 
82
112
  ### `createYakProvider(options)`
83
113
 
84
- Call once in your root/layout component. Sets up the widget, registers lifecycle hooks, and provides the API to all descendant components via Vue's `provide/inject`.
114
+ Call once in your root component. Returns a `YakApi` (same object `useYak()` injects).
85
115
 
86
- Returns a `YakApi` object (same as `useYak()`).
116
+ | Option | Type | Default | Description |
117
+ | --- | --- | --- | --- |
118
+ | `appId` | `string` | β€” | Your Yak app ID (required). |
119
+ | `mode` | `"chat" \| "voice" \| "both"` | `"chat"` | Which surfaces the widget exposes. |
120
+ | `trigger` | `boolean \| TriggerButtonConfig` | `false` | Show the floating pill. **Set `true`** to display it; `TriggerButtonConfig` recolors it. |
121
+ | `getConfig` | `ChatConfigProvider` | β€” | Async provider of routes + tools. Called on open / voice start. |
122
+ | `onToolCall` | `ToolCallHandler` | β€” | Executes a tool the assistant calls. |
123
+ | `onGraphQLSchemaCall` | `GraphQLSchemaHandler` | β€” | Handles GraphQL schema tool calls. |
124
+ | `onRESTSchemaCall` | `RESTSchemaHandler` | β€” | Handles REST/OpenAPI schema tool calls. |
125
+ | `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. |
87
128
 
88
- **Options:**
89
-
90
- | Option | Type | Description |
91
- |--------|------|-------------|
92
- | `appId` | `string` | Your Yak app ID |
93
- | `getConfig` | `ChatConfigProvider` | Async function returning routes + tools. Called on first open. |
94
- | `onToolCall` | `ToolCallHandler` | Handle tool invocations from the assistant |
95
- | `onGraphQLSchemaCall` | `GraphQLSchemaHandler` | Handle GraphQL schema tool calls |
96
- | `onRESTSchemaCall` | `RESTSchemaHandler` | Handle REST/OpenAPI schema tool calls |
97
- | `theme` | `Theme` | Position, color mode, and custom colors |
98
- | `onRedirect` | `(path: string) => void` | Navigation handler (defaults to `window.location.assign`) |
99
- | `disableRestartButton` | `boolean` | Hide the restart session button |
100
- | `trigger` | `boolean \| TriggerButtonConfig` | Built-in trigger button |
101
-
102
- ### `useYak()`
103
-
104
- Inject the widget API in any descendant component.
129
+ ### `YakApi`
105
130
 
106
131
  ```ts
107
- const {
108
- isOpen, // DeepReadonly<Ref<boolean>>
109
- isReady, // DeepReadonly<Ref<boolean>>
110
- open, // () => void
111
- close, // () => void
112
- openWithPrompt, // (prompt: string) => void
113
- subscribeToToolEvents, // (handler) => () => void
114
- } = useYak();
132
+ type YakApi = {
133
+ // chat
134
+ isOpen: DeepReadonly<Ref<boolean>>;
135
+ isReady: DeepReadonly<Ref<boolean>>;
136
+ chatLoading: DeepReadonly<Ref<boolean>>; // isOpen && !isReady
137
+ open: () => void;
138
+ close: () => void;
139
+ openWithPrompt: (prompt: string) => void;
140
+ subscribeToToolEvents: (handler: ToolCallEventHandler) => () => void;
141
+ // voice
142
+ voiceMachine: DeepReadonly<Ref<VoiceMachine>>; // { state, errorMessage? }
143
+ voiceLoading: DeepReadonly<Ref<boolean>>; // state === "connecting"
144
+ voiceStart: () => Promise<void>;
145
+ voiceStop: () => Promise<void>;
146
+ voiceToggle: () => Promise<void>;
147
+ };
115
148
  ```
116
149
 
117
- Throws if called outside a component tree where `createYakProvider` was used.
118
-
119
- ### `useYakToolEvent(handler)`
120
-
121
- Subscribe to tool call completion events. Unsubscribes automatically on component unmount.
122
-
123
150
  ## Logging
124
151
 
125
152
  ```ts
126
153
  import { enableYakLogging, disableYakLogging, isYakLoggingEnabled } from "@yak-io/vue";
127
154
 
128
- enableYakLogging(); // Enable verbose SDK logs
129
- disableYakLogging(); // Disable SDK logs
130
- isYakLoggingEnabled(); // β†’ boolean
155
+ enableYakLogging(); // verbose SDK logs
131
156
  ```
132
157
 
133
158
  ## Types
@@ -141,11 +166,13 @@ import type {
141
166
  ToolCallHandler,
142
167
  ToolCallEvent,
143
168
  Theme,
144
- TriggerButtonConfig,
169
+ WidgetMode,
145
170
  WidgetPosition,
171
+ VoiceState,
172
+ VoiceMachine,
146
173
  } from "@yak-io/vue";
147
174
  ```
148
175
 
149
176
  ## License
150
177
 
151
- Proprietary β€” see LICENSE file.
178
+ Proprietary β€” see [LICENSE](./LICENSE).
@@ -1,8 +1,9 @@
1
- import { type Ref, type DeepReadonly } from "vue";
2
- import { type TriggerButtonConfig, type ChatConfigProvider, type ToolCallHandler, type ToolCallEvent, type GraphQLSchemaHandler, type RESTSchemaHandler, type Theme } from "@yak-io/javascript";
1
+ import { type ChatConfigProvider, type GraphQLSchemaHandler, type RESTSchemaHandler, type Theme, type ToolCallEvent, type ToolCallHandler, type TriggerButtonConfig, type VoiceMachine, type WidgetMode } from "@yak-io/javascript";
2
+ import { type DeepReadonly, type Ref } from "vue";
3
3
  export type ToolCallEventHandler = (event: ToolCallEvent) => void;
4
4
  export type YakProviderOptions = {
5
5
  appId: string;
6
+ mode?: WidgetMode;
6
7
  getConfig?: ChatConfigProvider;
7
8
  onToolCall?: ToolCallHandler;
8
9
  onGraphQLSchemaCall?: GraphQLSchemaHandler;
@@ -12,37 +13,49 @@ export type YakProviderOptions = {
12
13
  disableRestartButton?: boolean;
13
14
  trigger?: boolean | TriggerButtonConfig;
14
15
  };
16
+ /** Reactive handle for controlling the Yak widget β€” chat + voice β€” from Vue. */
15
17
  export type YakApi = {
18
+ /** Whether the chat panel is currently open. */
16
19
  isOpen: DeepReadonly<Ref<boolean>>;
20
+ /** Whether the chat iframe is ready to receive messages. */
17
21
  isReady: DeepReadonly<Ref<boolean>>;
22
+ /** Whether the chat is opening but not yet interactive (`isOpen && !isReady`). */
23
+ chatLoading: DeepReadonly<Ref<boolean>>;
24
+ /** Open the chat panel. */
18
25
  open: () => void;
26
+ /** Close the chat panel. */
19
27
  close: () => void;
28
+ /** Open the chat panel and send a specific prompt. */
20
29
  openWithPrompt: (prompt: string) => void;
30
+ /** Subscribe to tool-call completion events; returns an unsubscribe function. */
21
31
  subscribeToToolEvents: (handler: ToolCallEventHandler) => () => void;
32
+ /** Current voice state-machine snapshot. `idle` when mode is `chat`. */
33
+ voiceMachine: DeepReadonly<Ref<VoiceMachine>>;
34
+ /** Whether the voice session is establishing its connection (`state === "connecting"`). */
35
+ voiceLoading: DeepReadonly<Ref<boolean>>;
36
+ /** Start a voice session. Must be invoked from a user gesture. */
37
+ voiceStart: () => Promise<void>;
38
+ /** Stop the current voice session. */
39
+ voiceStop: () => Promise<void>;
40
+ /** Toggle voice: start if idle/error, stop if active. */
41
+ voiceToggle: () => Promise<void>;
22
42
  };
23
43
  /**
24
- * Sets up the yak chat widget and provides it to descendant components.
44
+ * Sets up the yak widget (chat + voice) and provides it to descendants.
25
45
  * Call this once in a root/layout component.
26
46
  *
27
47
  * @example
28
48
  * ```ts
29
- * // App.vue <script setup>
30
- * import { createYakProvider } from "@yak-io/vue";
31
- *
32
49
  * createYakProvider({
33
50
  * appId: "my-app",
34
- * trigger: { label: "Ask with AI" },
51
+ * mode: "both",
52
+ * getConfig: async () => ({ routes: { routes: [], generated_at: "" } }),
35
53
  * });
36
54
  * ```
37
55
  */
38
56
  export declare function createYakProvider(options: YakProviderOptions): YakApi;
39
57
  /**
40
- * Access the yak chat widget API.
41
- *
42
- * @example
43
- * ```ts
44
- * const { open, isOpen, openWithPrompt } = useYak();
45
- * ```
58
+ * Access the yak widget API (chat + voice).
46
59
  *
47
60
  * @throws {Error} if used outside a component tree with createYakProvider
48
61
  */
@@ -50,15 +63,6 @@ export declare function useYak(): YakApi;
50
63
  /**
51
64
  * Subscribe to tool call completion events.
52
65
  * Automatically cleans up on component unmount.
53
- *
54
- * @example
55
- * ```ts
56
- * useYakToolEvent((event) => {
57
- * if (event.ok && event.name.startsWith("task.")) {
58
- * refreshTasks();
59
- * }
60
- * });
61
- * ```
62
66
  */
63
67
  export declare function useYakToolEvent(handler: ToolCallEventHandler): void;
64
68
  //# sourceMappingURL=composables.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"composables.d.ts","sourceRoot":"","sources":["../src/composables.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,GAAG,EACR,KAAK,YAAY,EAClB,MAAM,KAAK,CAAC;AACb,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,KAAK,EACX,MAAM,oBAAoB,CAAC;AAK5B,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAElE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAC3C,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IACrC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACnC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACpC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,qBAAqB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,MAAM,IAAI,CAAC;CACtE,CAAC;AAQF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CA6FrE;AAID;;;;;;;;;GASG;AACH,wBAAgB,MAAM,IAAI,MAAM,CAM/B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAUnE"}
1
+ {"version":3,"file":"composables.d.ts","sourceRoot":"","sources":["../src/composables.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EAGzB,KAAK,iBAAiB,EACtB,KAAK,KAAK,EACV,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,YAAY,EAMjB,KAAK,GAAG,EAGT,MAAM,KAAK,CAAC;AAIb,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAElE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAC3C,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IACrC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;CACzC,CAAC;AAEF,gFAAgF;AAChF,MAAM,MAAM,MAAM,GAAG;IAEnB,gDAAgD;IAChD,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACnC,4DAA4D;IAC5D,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACpC,kFAAkF;IAClF,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACxC,2BAA2B;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,sDAAsD;IACtD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,iFAAiF;IACjF,qBAAqB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,MAAM,IAAI,CAAC;IAErE,wEAAwE;IACxE,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;IAC9C,2FAA2F;IAC3F,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACzC,kEAAkE;IAClE,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,sCAAsC;IACtC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,yDAAyD;IACzD,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC,CAAC;AAQF;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAkHrE;AAID;;;;GAIG;AACH,wBAAgB,MAAM,IAAI,MAAM,CAM/B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAUnE"}
@@ -1,27 +1,25 @@
1
- import { ref, readonly, onMounted, onUnmounted, inject, provide, } from "vue";
2
- import { YakEmbed, } from "@yak-io/javascript";
3
- import { logger } from "@yak-io/javascript";
1
+ import { INITIAL_VOICE_MACHINE, logger, YakEmbed, } from "@yak-io/javascript";
2
+ import { computed, inject, onMounted, onUnmounted, provide, readonly, ref, } from "vue";
4
3
  // ── Injection key ───────────────────────────────────────────────────────────
5
4
  const YAK_KEY = Symbol("yak");
6
5
  // ── Provider composable ─────────────────────────────────────────────────────
7
6
  /**
8
- * Sets up the yak chat widget and provides it to descendant components.
7
+ * Sets up the yak widget (chat + voice) and provides it to descendants.
9
8
  * Call this once in a root/layout component.
10
9
  *
11
10
  * @example
12
11
  * ```ts
13
- * // App.vue <script setup>
14
- * import { createYakProvider } from "@yak-io/vue";
15
- *
16
12
  * createYakProvider({
17
13
  * appId: "my-app",
18
- * trigger: { label: "Ask with AI" },
14
+ * mode: "both",
15
+ * getConfig: async () => ({ routes: { routes: [], generated_at: "" } }),
19
16
  * });
20
17
  * ```
21
18
  */
22
19
  export function createYakProvider(options) {
23
20
  const isOpen = ref(false);
24
21
  const isReady = ref(false);
22
+ const voiceMachine = ref(INITIAL_VOICE_MACHINE);
25
23
  const toolEventSubscribers = new Set();
26
24
  const handleToolCallComplete = (event) => {
27
25
  logger.debug("Tool call completed, notifying subscribers:", {
@@ -42,8 +40,10 @@ export function createYakProvider(options) {
42
40
  (typeof window !== "undefined" ? (path) => window.location.assign(path) : undefined);
43
41
  const embed = new YakEmbed({
44
42
  appId: options.appId,
43
+ mode: options.mode,
45
44
  theme: options.theme,
46
45
  trigger: options.trigger ?? false,
46
+ getConfig: options.getConfig,
47
47
  onToolCall: options.onToolCall,
48
48
  onGraphQLSchemaCall: options.onGraphQLSchemaCall,
49
49
  onRESTSchemaCall: options.onRESTSchemaCall,
@@ -51,12 +51,13 @@ export function createYakProvider(options) {
51
51
  options: { disableRestartButton: options.disableRestartButton },
52
52
  onToolCallComplete: handleToolCallComplete,
53
53
  });
54
- // Subscribe to state changes
55
54
  embed.onStateChange((state) => {
56
55
  isOpen.value = state.isOpen;
57
56
  isReady.value = state.isReady;
58
57
  });
59
- // Mount/unmount with component lifecycle
58
+ embed.onVoiceStateChange((m) => {
59
+ voiceMachine.value = m;
60
+ });
60
61
  onMounted(() => {
61
62
  embed.mount();
62
63
  });
@@ -83,9 +84,20 @@ export function createYakProvider(options) {
83
84
  }
84
85
  });
85
86
  }
87
+ const voiceStart = async () => {
88
+ try {
89
+ await embed.voiceStart();
90
+ }
91
+ catch (err) {
92
+ logger.warn("Voice start failed", err);
93
+ }
94
+ };
95
+ const chatLoading = computed(() => isOpen.value && !isReady.value);
96
+ const voiceLoading = computed(() => voiceMachine.value.state === "connecting");
86
97
  const api = {
87
98
  isOpen: readonly(isOpen),
88
99
  isReady: readonly(isReady),
100
+ chatLoading,
89
101
  open: () => embed.open(),
90
102
  close: () => embed.close(),
91
103
  openWithPrompt: (prompt) => embed.openWithPrompt(prompt),
@@ -95,18 +107,18 @@ export function createYakProvider(options) {
95
107
  toolEventSubscribers.delete(handler);
96
108
  };
97
109
  },
110
+ voiceMachine: readonly(voiceMachine),
111
+ voiceLoading,
112
+ voiceStart,
113
+ voiceStop: () => embed.voiceStop(),
114
+ voiceToggle: () => embed.voiceToggle(),
98
115
  };
99
116
  provide(YAK_KEY, api);
100
117
  return api;
101
118
  }
102
119
  // ── Consumer composables ────────────────────────────────────────────────────
103
120
  /**
104
- * Access the yak chat widget API.
105
- *
106
- * @example
107
- * ```ts
108
- * const { open, isOpen, openWithPrompt } = useYak();
109
- * ```
121
+ * Access the yak widget API (chat + voice).
110
122
  *
111
123
  * @throws {Error} if used outside a component tree with createYakProvider
112
124
  */
@@ -120,15 +132,6 @@ export function useYak() {
120
132
  /**
121
133
  * Subscribe to tool call completion events.
122
134
  * Automatically cleans up on component unmount.
123
- *
124
- * @example
125
- * ```ts
126
- * useYakToolEvent((event) => {
127
- * if (event.ok && event.name.startsWith("task.")) {
128
- * refreshTasks();
129
- * }
130
- * });
131
- * ```
132
135
  */
133
136
  export function useYakToolEvent(handler) {
134
137
  const api = inject(YAK_KEY);
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { useYak, useYakToolEvent, createYakProvider } from "./composables.js";
2
- export type { YakProviderOptions, YakApi, ToolCallEventHandler } from "./composables.js";
3
- export { enableYakLogging, disableYakLogging, isYakLoggingEnabled } from "@yak-io/javascript";
4
- export type { GraphQLSchemaHandler, RESTSchemaHandler, GraphQLRequest, RESTRequest, ToolCallHandler, ToolCallEvent, SchemaSource, GraphQLSchemaSource, OpenAPISchemaSource, Theme, ThemeColors, TriggerButtonConfig, WidgetPosition, ChatConfigProvider, } from "@yak-io/javascript";
1
+ export type { ChatConfigProvider, GraphQLRequest, GraphQLSchemaHandler, GraphQLSchemaSource, OpenAPISchemaSource, RESTRequest, RESTSchemaHandler, SchemaSource, Theme, ThemeColors, ToolCallEvent, ToolCallHandler, TriggerButtonConfig, VoiceMachine, VoiceState, WidgetMode, WidgetPosition, } from "@yak-io/javascript";
2
+ export { disableYakLogging, enableYakLogging, isYakLoggingEnabled } from "@yak-io/javascript";
3
+ export type { ToolCallEventHandler, YakApi, YakProviderOptions } from "./composables.js";
4
+ export { createYakProvider, useYak, useYakToolEvent } from "./composables.js";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,YAAY,EAAE,kBAAkB,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGzF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9F,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,eAAe,EACf,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,EACL,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,kBAAkB,GACnB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,KAAK,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,UAAU,EACV,cAAc,GACf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9F,YAAY,EAAE,oBAAoB,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // Public API
2
- export { useYak, useYakToolEvent, createYakProvider } from "./composables.js";
3
2
  // Re-export logging utilities
4
- export { enableYakLogging, disableYakLogging, isYakLoggingEnabled } from "@yak-io/javascript";
3
+ export { disableYakLogging, enableYakLogging, isYakLoggingEnabled } from "@yak-io/javascript";
4
+ export { createYakProvider, useYak, useYakToolEvent } from "./composables.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yak-io/vue",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Vue 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,17 +42,18 @@
41
42
  "./package.json": "./package.json"
42
43
  },
43
44
  "dependencies": {
44
- "@yak-io/javascript": "0.7.0"
45
+ "@yak-io/javascript": "0.9.0"
45
46
  },
46
47
  "peerDependencies": {
47
48
  "vue": "^3.3.0"
48
49
  },
49
50
  "devDependencies": {
50
- "@types/node": "^24.12.0",
51
+ "@types/node": "^24.12.4",
51
52
  "typescript": "^5.3.0",
52
- "vue": "^3.5.16",
53
+ "vue": "^3.5.34",
53
54
  "@repo/typescript-config": "0.0.0"
54
55
  },
56
+ "homepage": "https://docs.yak.io/docs/sdks/vue",
55
57
  "scripts": {
56
58
  "build": "tsc",
57
59
  "check-types": "tsc --noEmit",