@yak-io/vue 0.3.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).
@@ -13,16 +13,31 @@ export type YakProviderOptions = {
13
13
  disableRestartButton?: boolean;
14
14
  trigger?: boolean | TriggerButtonConfig;
15
15
  };
16
+ /** Reactive handle for controlling the Yak widget β€” chat + voice β€” from Vue. */
16
17
  export type YakApi = {
18
+ /** Whether the chat panel is currently open. */
17
19
  isOpen: DeepReadonly<Ref<boolean>>;
20
+ /** Whether the chat iframe is ready to receive messages. */
18
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. */
19
25
  open: () => void;
26
+ /** Close the chat panel. */
20
27
  close: () => void;
28
+ /** Open the chat panel and send a specific prompt. */
21
29
  openWithPrompt: (prompt: string) => void;
30
+ /** Subscribe to tool-call completion events; returns an unsubscribe function. */
22
31
  subscribeToToolEvents: (handler: ToolCallEventHandler) => () => void;
32
+ /** Current voice state-machine snapshot. `idle` when mode is `chat`. */
23
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. */
24
37
  voiceStart: () => Promise<void>;
38
+ /** Stop the current voice session. */
25
39
  voiceStop: () => Promise<void>;
40
+ /** Toggle voice: start if idle/error, stop if active. */
26
41
  voiceToggle: () => Promise<void>;
27
42
  };
28
43
  /**
@@ -1 +1 @@
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,EACL,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,MAAM,MAAM,MAAM,GAAG;IAEnB,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;IAErE,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;IAC9C,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC,CAAC;AAQF;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CA6GrE;AAID;;;;GAIG;AACH,wBAAgB,MAAM,IAAI,MAAM,CAM/B;AAED;;;GAGG;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,5 +1,5 @@
1
1
  import { INITIAL_VOICE_MACHINE, logger, YakEmbed, } from "@yak-io/javascript";
2
- import { inject, onMounted, onUnmounted, provide, readonly, ref, } from "vue";
2
+ import { computed, inject, onMounted, onUnmounted, provide, readonly, ref, } from "vue";
3
3
  // ── Injection key ───────────────────────────────────────────────────────────
4
4
  const YAK_KEY = Symbol("yak");
5
5
  // ── Provider composable ─────────────────────────────────────────────────────
@@ -92,9 +92,12 @@ export function createYakProvider(options) {
92
92
  logger.warn("Voice start failed", err);
93
93
  }
94
94
  };
95
+ const chatLoading = computed(() => isOpen.value && !isReady.value);
96
+ const voiceLoading = computed(() => voiceMachine.value.state === "connecting");
95
97
  const api = {
96
98
  isOpen: readonly(isOpen),
97
99
  isReady: readonly(isReady),
100
+ chatLoading,
98
101
  open: () => embed.open(),
99
102
  close: () => embed.close(),
100
103
  openWithPrompt: (prompt) => embed.openWithPrompt(prompt),
@@ -105,6 +108,7 @@ export function createYakProvider(options) {
105
108
  };
106
109
  },
107
110
  voiceMachine: readonly(voiceMachine),
111
+ voiceLoading,
108
112
  voiceStart,
109
113
  voiceStop: () => embed.voiceStop(),
110
114
  voiceToggle: () => embed.voiceToggle(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yak-io/vue",
3
- "version": "0.3.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,7 +42,7 @@
41
42
  "./package.json": "./package.json"
42
43
  },
43
44
  "dependencies": {
44
- "@yak-io/javascript": "0.8.0"
45
+ "@yak-io/javascript": "0.9.0"
45
46
  },
46
47
  "peerDependencies": {
47
48
  "vue": "^3.3.0"
@@ -52,6 +53,7 @@
52
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",