@boldvideo/bold-js 1.15.0 → 1.15.2

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/AGENTS.md CHANGED
@@ -134,6 +134,7 @@ bold.trackPageView() // Track page views
134
134
  - Follow existing patterns in the codebase
135
135
  - Run `pnpm run lint` before committing
136
136
  - Keep the SDK lightweight (minimal dependencies)
137
+ - **Keep `llms.txt` up to date** when adding/changing public API methods or types
137
138
 
138
139
  **Ask first:**
139
140
  - Adding new dependencies
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @boldvideo/bold-js
2
2
 
3
+ ## 1.15.2
4
+
5
+ ### Patch Changes
6
+
7
+ - e35a6d4: Enhanced llms.txt for better AI/LLM consumption
8
+
9
+ - Added `{ data: T }` return type pattern to Quick Start examples
10
+ - Documented `ClientOptions` type with all configuration options
11
+ - Added `getConversation()` method to AI Methods section
12
+ - Included complete `AIEvent` union type with all 6 event types
13
+ - Added inline definitions for `Video`, `Segment`, and `Recommendation` types
14
+ - New Error Handling section covering HTTP errors and streaming errors
15
+ - Marked Analytics section as "Browser Only" with usage details
16
+ - Documented that `videos.get(id)` accepts both ID and slug
17
+
18
+ ## 1.15.1
19
+
20
+ ### Patch Changes
21
+
22
+ - d8a142c: Add `chatDisclaimer` field to Settings type for displaying custom disclaimer text in the chat interface.
23
+
3
24
  ## 1.15.0
4
25
 
5
26
  ### Minor Changes
package/dist/index.d.ts CHANGED
@@ -175,6 +175,7 @@ type Settings = {
175
175
  aiAvatar: string;
176
176
  aiName: string;
177
177
  aiGreeting?: string;
178
+ chatDisclaimer?: string;
178
179
  hasAi: boolean;
179
180
  account: Account;
180
181
  faviconUrl?: string;
package/llms.txt CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  > TypeScript client for the Bold Video API. Fetch videos, playlists, settings. Stream AI responses. Track analytics.
4
4
 
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @boldvideo/bold-js
9
+ ```
10
+
5
11
  ## Quick Start
6
12
 
7
13
  ```typescript
@@ -9,53 +15,86 @@ import { createClient } from '@boldvideo/bold-js';
9
15
 
10
16
  const bold = createClient('your-api-key');
11
17
 
12
- // Fetch videos
13
- const videos = await bold.videos.list();
14
- const video = await bold.videos.get('video-id');
18
+ // Content methods return { data: T }
19
+ const { data: videos } = await bold.videos.list();
20
+ const { data: video } = await bold.videos.get('video-id-or-slug');
15
21
 
16
- // AI-powered recommendations
17
- const recs = await bold.ai.recommendations({ topics: ['sales', 'negotiation'], stream: false });
18
- console.log(recs.guidance);
19
-
20
- // AI streaming
22
+ // AI streaming (default)
21
23
  const stream = await bold.ai.chat({ prompt: 'How do I price my SaaS?' });
22
24
  for await (const event of stream) {
23
- if (event.type === 'text_delta') process.stdout.write(event.delta);
25
+ switch (event.type) {
26
+ case 'text_delta': process.stdout.write(event.delta); break;
27
+ case 'sources': console.log('Found:', event.sources.length); break;
28
+ case 'message_complete': console.log('Done:', event.conversationId); break;
29
+ case 'error': console.error(event.message); break;
30
+ }
24
31
  }
32
+
33
+ // AI non-streaming
34
+ const response = await bold.ai.recommendations({
35
+ topics: ['sales', 'negotiation'],
36
+ stream: false
37
+ });
38
+ console.log(response.guidance);
25
39
  ```
26
40
 
27
- ## API Reference
41
+ ## Client Configuration
42
+
43
+ ```typescript
44
+ createClient(apiKey: string, options?: ClientOptions)
28
45
 
29
- ### Client
46
+ interface ClientOptions {
47
+ baseURL?: string; // Default: 'https://app.boldvideo.io/api/v1/'
48
+ debug?: boolean; // Log requests (default: false)
49
+ headers?: Record<string, string>; // Additional headers
50
+ }
51
+ ```
30
52
 
31
- - `createClient(apiKey, options?)` - Create SDK instance
53
+ ## Content Methods
32
54
 
33
- ### Content
55
+ All content methods return `Promise<{ data: T }>`.
34
56
 
35
- - `bold.settings()` - Channel settings, menus, featured playlists
36
- - `bold.videos.list()` - List videos
37
- - `bold.videos.get(id)` - Get video by ID
57
+ - `bold.settings(videoLimit?)` - Channel settings, menus, featured playlists
58
+ - `bold.videos.list(limit?)` - List videos (default limit: 12)
59
+ - `bold.videos.get(id)` - Get video by ID or slug
38
60
  - `bold.videos.search(query)` - Search videos
39
61
  - `bold.playlists.list()` - List playlists
40
- - `bold.playlists.get(id)` - Get playlist by ID
62
+ - `bold.playlists.get(id)` - Get playlist with videos
41
63
 
42
- ### AI Methods
64
+ ## AI Methods
43
65
 
44
66
  All AI methods return `AsyncIterable<AIEvent>` (streaming) or `Promise<AIResponse>` (non-streaming).
67
+ Default is streaming (`stream: true`).
45
68
 
46
- - `bold.ai.chat(options)` - Conversational AI for Q&A (pass `videoId` to scope to a video)
47
- - `bold.ai.search(options)` - Semantic search with synthesis
48
- - `bold.ai.recommendations(options)` - AI-powered video recommendations based on topics
69
+ - `bold.ai.chat(options: ChatOptions)` - Conversational Q&A (library-wide or video-scoped)
70
+ - `bold.ai.search(options: SearchOptions)` - Semantic search with AI summary
71
+ - `bold.ai.recommendations(options: RecommendationsOptions)` - Topic-based video recommendations
72
+ - `bold.ai.getConversation(id: string)` - Retrieve conversation history by ID
49
73
 
50
- **Deprecated aliases** (still work but will be removed):
51
- - `bold.ai.ask(options)` use `chat()`
52
- - `bold.ai.coach(options)` use `chat()`
53
- - `bold.ai.recommend(options)` use `recommendations()`
74
+ **Deprecated aliases** (still work):
75
+ - `bold.ai.ask()` -> use `chat()`
76
+ - `bold.ai.coach()` -> use `chat()`
77
+ - `bold.ai.recommend()` -> use `recommendations()`
54
78
 
55
- ### Analytics
79
+ ## AI Streaming Events
56
80
 
57
- - `bold.trackEvent(event)` - Track video events (play, pause, complete)
58
- - `bold.trackPageView(data)` - Track page views
81
+ ```typescript
82
+ type AIEvent =
83
+ | { type: "message_start"; conversationId?: string; videoId?: string }
84
+ | { type: "sources"; sources: Segment[] }
85
+ | { type: "text_delta"; delta: string }
86
+ | { type: "recommendations"; recommendations: Recommendation[] }
87
+ | { type: "message_complete";
88
+ conversationId?: string;
89
+ content: string;
90
+ citations: Segment[];
91
+ responseType: "answer" | "clarification";
92
+ usage?: AIUsage;
93
+ context?: AIContextMessage[];
94
+ recommendations?: Recommendation[];
95
+ guidance?: string }
96
+ | { type: "error"; code: string; message: string; retryable: boolean }
97
+ ```
59
98
 
60
99
  ## AI Options
61
100
 
@@ -63,13 +102,13 @@ All AI methods return `AsyncIterable<AIEvent>` (streaming) or `Promise<AIRespons
63
102
 
64
103
  ```typescript
65
104
  {
66
- prompt: string; // Question to ask (required)
67
- stream?: boolean; // Default: true
68
- videoId?: string; // If set, scope to this video
69
- currentTime?: number; // Current playback position (with videoId)
70
- conversationId?: string; // Continue existing conversation
71
- collectionId?: string; // Filter to collection
72
- tags?: string[]; // Filter by tags
105
+ prompt: string; // Required
106
+ stream?: boolean; // Default: true
107
+ videoId?: string; // Scope to specific video
108
+ currentTime?: number; // Playback position (with videoId)
109
+ conversationId?: string; // Continue conversation
110
+ collectionId?: string; // Filter to collection
111
+ tags?: string[]; // Filter by tags
73
112
  }
74
113
  ```
75
114
 
@@ -77,13 +116,13 @@ All AI methods return `AsyncIterable<AIEvent>` (streaming) or `Promise<AIRespons
77
116
 
78
117
  ```typescript
79
118
  {
80
- prompt: string; // Search query (required)
81
- stream?: boolean; // Default: true
82
- limit?: number; // Max results
83
- collectionId?: string; // Filter to collection
84
- videoId?: string; // Search within specific video
85
- tags?: string[]; // Filter by tags
86
- context?: AIContextMessage[]; // Conversation context
119
+ prompt: string; // Required
120
+ stream?: boolean; // Default: true
121
+ limit?: number; // Max results
122
+ collectionId?: string;
123
+ videoId?: string; // Search within video
124
+ tags?: string[];
125
+ context?: AIContextMessage[];
87
126
  }
88
127
  ```
89
128
 
@@ -91,26 +130,118 @@ All AI methods return `AsyncIterable<AIEvent>` (streaming) or `Promise<AIRespons
91
130
 
92
131
  ```typescript
93
132
  {
94
- topics: string[]; // Topics to find content for (required)
95
- stream?: boolean; // Default: true
96
- limit?: number; // Max videos per topic (default: 5, max: 20)
97
- collectionId?: string; // Filter to collection
98
- tags?: string[]; // Filter by tags
99
- includeGuidance?: boolean; // Include AI learning path narrative (default: true)
100
- context?: AIContextMessage[]; // Previous conversation turns for follow-ups
133
+ topics: string[]; // Required (max: 10)
134
+ stream?: boolean; // Default: true
135
+ limit?: number; // Max per topic (default: 5, max: 20)
136
+ collectionId?: string;
137
+ tags?: string[];
138
+ includeGuidance?: boolean; // Default: true
139
+ context?: AIContextMessage[];
140
+ }
141
+ ```
142
+
143
+ ## Core Types
144
+
145
+ ### Video
146
+
147
+ ```typescript
148
+ {
149
+ id: string;
150
+ slug?: string;
151
+ title: string;
152
+ description: string | null;
153
+ duration: number;
154
+ publishedAt: string;
155
+ playbackId: string;
156
+ streamUrl: string;
157
+ thumbnail: string;
158
+ tags?: string[];
159
+ metaData: { title: string; description: string; image: string | null };
160
+ chapters?: string;
161
+ attachments?: VideoAttachment[];
162
+ transcript?: { text: string; json: any };
163
+ }
164
+ ```
165
+
166
+ ### Segment (for sources/citations)
167
+
168
+ ```typescript
169
+ {
170
+ id: string;
171
+ videoId: string;
172
+ title: string;
173
+ text: string; // Transcript excerpt
174
+ timestamp: number; // Start seconds
175
+ timestampEnd: number; // End seconds
176
+ playbackId: string;
177
+ speaker?: string;
178
+ cited?: boolean;
179
+ }
180
+ ```
181
+
182
+ ### Recommendation
183
+
184
+ ```typescript
185
+ {
186
+ topic: string;
187
+ videos: Array<{
188
+ videoId: string;
189
+ title: string;
190
+ playbackId: string;
191
+ relevance: number;
192
+ reason: string;
193
+ }>;
194
+ }
195
+ ```
196
+
197
+ ### Other types exported
198
+
199
+ `Playlist`, `Settings`, `Portal`, `MenuItem`, `AIResponse`, `AIUsage`, `AIContextMessage`, `Conversation`, `ConversationMessage`, `RecommendationsResponse`
200
+
201
+ ## Error Handling
202
+
203
+ ### HTTP Errors
204
+
205
+ SDK throws on non-2xx responses:
206
+ - 401: Invalid API key
207
+ - 403: Forbidden (check permissions)
208
+ - 429: Rate limited (retry with backoff)
209
+ - 500: Server error (retry)
210
+
211
+ ```typescript
212
+ try {
213
+ const { data } = await bold.videos.list();
214
+ } catch (error) {
215
+ if (error.response?.status === 401) {
216
+ console.error('Invalid API key');
217
+ }
218
+ }
219
+ ```
220
+
221
+ ### Streaming Errors
222
+
223
+ Handle error events in stream:
224
+
225
+ ```typescript
226
+ for await (const event of stream) {
227
+ if (event.type === 'error') {
228
+ console.error(`[${event.code}] ${event.message}`);
229
+ if (event.retryable) { /* retry logic */ }
230
+ }
101
231
  }
102
232
  ```
103
233
 
104
- ## Types
234
+ ## Analytics (Browser Only)
105
235
 
106
- Key types exported:
236
+ These methods require browser globals (`window`, `document`, `navigator`).
237
+ Do not use in Node.js.
107
238
 
108
- - `Video`, `Playlist`, `Settings`, `Portal`
109
- - `AIEvent`, `AIResponse`, `Source`, `AIUsage`
110
- - `ChatOptions`, `SearchOptions`
111
- - `RecommendationsOptions`, `RecommendationsResponse`, `Recommendation`, `RecommendationVideo`
239
+ - `bold.trackEvent(video, event)` - Track video playback
240
+ - `video`: `{ id, title, duration }`
241
+ - `event`: DOM Event (`play`, `pause`, `timeupdate`, `loadedmetadata`)
242
+ - Note: `timeupdate` throttled to 5 seconds
112
243
 
113
- All response types use camelCase (e.g., `video.playbackId`, `video.publishedAt`, `settings.featuredPlaylists`, `source.videoId`).
244
+ - `bold.trackPageView(title: string)` - Track page views
114
245
 
115
246
  ## Links
116
247
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@boldvideo/bold-js",
3
3
  "license": "MIT",
4
- "version": "1.15.0",
4
+ "version": "1.15.2",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",