@boldvideo/bold-js 1.4.0 → 1.5.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/AGENTS.md CHANGED
@@ -46,11 +46,23 @@ This project uses [Changesets](https://github.com/changesets/changesets) with au
46
46
  - Removes the changeset files
47
47
  - When you merge that Release PR, the workflow automatically publishes to npm
48
48
 
49
+ ### Manual Release (when you need to publish immediately)
50
+
51
+ If you need to release immediately without waiting for the Release PR:
52
+
53
+ ```bash
54
+ pnpm changeset version # Consume changesets, bump version, update CHANGELOG
55
+ git add -A && git commit -m "chore: release vX.Y.Z"
56
+ git tag vX.Y.Z
57
+ git push origin main --tags
58
+ ```
59
+
60
+ The `release.yml` workflow will automatically publish to npm when it sees the `v*` tag.
61
+
49
62
  ### Important Notes
50
63
 
51
- - **Never run `pnpm changeset version` or `pnpm changeset publish` locally** - the GitHub Action handles this automatically
52
64
  - The CI workflow (`ci.yml`) runs `pnpm run build` which generates the `dist/` folder - this ensures compiled files are always included in the published package
53
- - The `release.yml` workflow can also publish when a `v*` tag is pushed (alternative release method)
65
+ - The `release.yml` workflow publishes when a `v*` tag is pushed
54
66
 
55
67
  ## Project Structure
56
68
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @boldvideo/bold-js
2
2
 
3
+ ## 1.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 21267d9: Fix SSE parsing to process final 'complete' event when stream closes without trailing newline
8
+
9
+ ## 1.5.0
10
+
11
+ ### Minor Changes
12
+
13
+ - c86e99c: Add conversation context support to AI Search
14
+
15
+ - Added `context` parameter to `SearchOptions` for passing conversation history
16
+ - Added `context` field to `AIResponse` for receiving updated conversation context
17
+ - Added `AIContextMessage` type for type-safe context messages
18
+ - Updated README with multi-turn conversation example
19
+
20
+ Usage:
21
+
22
+ ```typescript
23
+ const first = await bold.ai.search({
24
+ prompt: "How do designers find clients?",
25
+ stream: false,
26
+ });
27
+ const followUp = await bold.ai.search({
28
+ prompt: "What about cold outreach?",
29
+ context: first.context,
30
+ stream: false,
31
+ });
32
+ ```
33
+
34
+ ### Patch Changes
35
+
36
+ - c961807: Fix AI search SSE stream termination: wait for 'complete' event instead of closing on 'message_complete'
37
+
38
+ - Added missing event types to AIEvent union: complete, token, answer
39
+ - Fixed parseSSE to terminate on 'complete' or 'error' events
40
+ - Added optional fields to match backend spec (query, context, response_id)
41
+
3
42
  ## 1.4.0
4
43
 
5
44
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -232,11 +232,14 @@ async function* parseSSE(response) {
232
232
  try {
233
233
  while (true) {
234
234
  const { done, value } = await reader.read();
235
- if (done)
236
- break;
237
- buffer += decoder.decode(value, { stream: true });
235
+ if (value) {
236
+ buffer += decoder.decode(value, { stream: true });
237
+ }
238
+ if (done) {
239
+ buffer += decoder.decode();
240
+ }
238
241
  const lines = buffer.split(/\r?\n\r?\n/);
239
- buffer = lines.pop() || "";
242
+ buffer = done ? "" : lines.pop() || "";
240
243
  for (const line of lines) {
241
244
  const trimmed = line.trim();
242
245
  if (!trimmed || !trimmed.startsWith("data:"))
@@ -247,13 +250,15 @@ async function* parseSSE(response) {
247
250
  try {
248
251
  const event = JSON.parse(json);
249
252
  yield event;
250
- if (event.type === "message_complete" || event.type === "error") {
253
+ if (event.type === "complete" || event.type === "error") {
251
254
  await reader.cancel();
252
255
  return;
253
256
  }
254
257
  } catch {
255
258
  }
256
259
  }
260
+ if (done)
261
+ break;
257
262
  }
258
263
  } finally {
259
264
  reader.releaseLock();
package/dist/index.d.ts CHANGED
@@ -208,9 +208,18 @@ type AIEvent = {
208
208
  } | {
209
209
  type: "sources";
210
210
  sources: Source[];
211
+ query?: string;
211
212
  } | {
212
213
  type: "text_delta";
213
214
  delta: string;
215
+ } | {
216
+ type: "token";
217
+ content: string;
218
+ } | {
219
+ type: "answer";
220
+ content: string;
221
+ response_id?: string;
222
+ context?: AIContextMessage[];
214
223
  } | {
215
224
  type: "clarification";
216
225
  questions: string[];
@@ -218,7 +227,10 @@ type AIEvent = {
218
227
  type: "message_complete";
219
228
  content: string;
220
229
  sources: Source[];
221
- usage: AIUsage;
230
+ usage?: AIUsage;
231
+ context?: AIContextMessage[];
232
+ } | {
233
+ type: "complete";
222
234
  } | {
223
235
  type: "error";
224
236
  code: string;
package/dist/index.js CHANGED
@@ -194,11 +194,14 @@ async function* parseSSE(response) {
194
194
  try {
195
195
  while (true) {
196
196
  const { done, value } = await reader.read();
197
- if (done)
198
- break;
199
- buffer += decoder.decode(value, { stream: true });
197
+ if (value) {
198
+ buffer += decoder.decode(value, { stream: true });
199
+ }
200
+ if (done) {
201
+ buffer += decoder.decode();
202
+ }
200
203
  const lines = buffer.split(/\r?\n\r?\n/);
201
- buffer = lines.pop() || "";
204
+ buffer = done ? "" : lines.pop() || "";
202
205
  for (const line of lines) {
203
206
  const trimmed = line.trim();
204
207
  if (!trimmed || !trimmed.startsWith("data:"))
@@ -209,13 +212,15 @@ async function* parseSSE(response) {
209
212
  try {
210
213
  const event = JSON.parse(json);
211
214
  yield event;
212
- if (event.type === "message_complete" || event.type === "error") {
215
+ if (event.type === "complete" || event.type === "error") {
213
216
  await reader.cancel();
214
217
  return;
215
218
  }
216
219
  } catch {
217
220
  }
218
221
  }
222
+ if (done)
223
+ break;
219
224
  }
220
225
  } finally {
221
226
  reader.releaseLock();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@boldvideo/bold-js",
3
3
  "license": "MIT",
4
- "version": "1.4.0",
4
+ "version": "1.5.1",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",