@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 +14 -2
- package/CHANGELOG.md +39 -0
- package/dist/index.cjs +10 -5
- package/dist/index.d.ts +13 -1
- package/dist/index.js +10 -5
- package/package.json +1 -1
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
|
|
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 (
|
|
236
|
-
|
|
237
|
-
|
|
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 === "
|
|
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
|
|
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 (
|
|
198
|
-
|
|
199
|
-
|
|
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 === "
|
|
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();
|