blun-king-cli 9.1.582 → 9.1.584
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/CHANGELOG.md +13 -0
- package/blun.mjs +33 -13
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
## 9.1.584 - 2026-09-08
|
|
2
|
+
|
|
3
|
+
- WebSearch forwards caller cancellation through the tool and managed HTTP search request, including response-body reads.
|
|
4
|
+
- Already cancelled searches do not start provider work. Cancellation during credential lookup prevents a later search request; late search results are withheld.
|
|
5
|
+
- Complete, partial and empty-result handling, citation output and normal authentication fallback remain unchanged. No new timeout or Telegram routing change.
|
|
6
|
+
|
|
7
|
+
## 9.1.583 - 2026-09-08
|
|
8
|
+
|
|
9
|
+
- FetchURL now passes caller cancellation through the tool and both fetch providers to the HTTP request.
|
|
10
|
+
- An aborted managed fetch no longer starts a local fallback, and a late provider result cannot become source evidence after cancellation.
|
|
11
|
+
- Normal fetch failures still allow the existing fallback. No new timeout is introduced; Telegram routing and model requests are unchanged.
|
|
12
|
+
|
|
13
|
+
|
|
1
14
|
# 9.1.582 - 2026-09-08
|
|
2
15
|
|
|
3
16
|
- Stop oversized local page responses while reading their body, including responses without a reliable Content-Length header. Cancel the stream when received bytes exceed the existing ten MiB limit.
|
package/blun.mjs
CHANGED
|
@@ -265663,9 +265663,11 @@ var init_fetch_url = __esmMin((() => {
|
|
|
265663
265663
|
execute: (ctx) => this.execution(args, ctx)
|
|
265664
265664
|
};
|
|
265665
265665
|
}
|
|
265666
|
-
async execution(args, { toolCallId }) {
|
|
265666
|
+
async execution(args, { toolCallId, signal }) {
|
|
265667
265667
|
try {
|
|
265668
|
-
|
|
265668
|
+
signal?.throwIfAborted();
|
|
265669
|
+
const { content, kind } = await this.fetcher.fetch(args.url, { toolCallId, signal });
|
|
265670
|
+
signal?.throwIfAborted();
|
|
265669
265671
|
return formatResearchPage({ ...args, content, kind });
|
|
265670
265672
|
} catch (error) {
|
|
265671
265673
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -265738,16 +265740,18 @@ var init_web_search = __esmMin((() => {
|
|
|
265738
265740
|
execute: (ctx) => this.execution(args, ctx)
|
|
265739
265741
|
};
|
|
265740
265742
|
}
|
|
265741
|
-
async execution(args, { toolCallId, }) {
|
|
265743
|
+
async execution(args, { toolCallId, signal }) {
|
|
265742
265744
|
try {
|
|
265745
|
+
signal?.throwIfAborted();
|
|
265743
265746
|
let failedSources = 0;
|
|
265744
|
-
const opts = { toolCallId, onNotice: notice => {
|
|
265747
|
+
const opts = { toolCallId, signal, onNotice: notice => {
|
|
265745
265748
|
if (notice.code === 'partial-sources' && Number.isInteger(notice.failedSources)
|
|
265746
265749
|
&& notice.failedSources > 0 && notice.failedSources <= 128) {
|
|
265747
265750
|
failedSources = Math.max(failedSources, notice.failedSources);
|
|
265748
265751
|
}
|
|
265749
265752
|
} };
|
|
265750
265753
|
const results = await this.provider.search(args.query, opts);
|
|
265754
|
+
signal?.throwIfAborted();
|
|
265751
265755
|
const builder = new ToolResultBuilder({ maxLineLength: null });
|
|
265752
265756
|
if (failedSources > 0) {
|
|
265753
265757
|
if (results.length === 0)
|
|
@@ -315114,11 +315118,13 @@ var init_local_fetch_url = __esmMin((() => {
|
|
|
315114
315118
|
this.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
315115
315119
|
this.allowPrivateAddresses = options.allowPrivateAddresses ?? false;
|
|
315116
315120
|
}
|
|
315117
|
-
async fetch(url,
|
|
315121
|
+
async fetch(url, options) {
|
|
315122
|
+
options?.signal?.throwIfAborted();
|
|
315118
315123
|
assertSafeFetchTarget(url, this.allowPrivateAddresses);
|
|
315119
315124
|
const response = await this.fetchImpl(url, {
|
|
315120
315125
|
method: "GET",
|
|
315121
|
-
headers: { "User-Agent": this.userAgent }
|
|
315126
|
+
headers: { "User-Agent": this.userAgent },
|
|
315127
|
+
signal: options?.signal
|
|
315122
315128
|
});
|
|
315123
315129
|
if (response.status >= 400) {
|
|
315124
315130
|
await response.body?.cancel().catch(() => {});
|
|
@@ -315195,18 +315201,21 @@ var init_blun_fetch_url = __esmMin((() => {
|
|
|
315195
315201
|
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
315196
315202
|
}
|
|
315197
315203
|
async fetch(url, options) {
|
|
315204
|
+
const signal = options?.signal;
|
|
315205
|
+
signal?.throwIfAborted();
|
|
315198
315206
|
try {
|
|
315199
315207
|
return {
|
|
315200
|
-
content: await this.fetchViaBlun(url, options?.toolCallId),
|
|
315208
|
+
content: await this.fetchViaBlun(url, options?.toolCallId, signal),
|
|
315201
315209
|
kind: "extracted"
|
|
315202
315210
|
};
|
|
315203
315211
|
} catch {
|
|
315212
|
+
signal?.throwIfAborted();
|
|
315204
315213
|
return this.localFallback.fetch(url, options ?? {});
|
|
315205
315214
|
}
|
|
315206
315215
|
}
|
|
315207
|
-
async fetchViaBlun(url, toolCallId) {
|
|
315216
|
+
async fetchViaBlun(url, toolCallId, signal) {
|
|
315208
315217
|
const bodyJson = JSON.stringify({ url });
|
|
315209
|
-
const response = await this.post(bodyJson, toolCallId);
|
|
315218
|
+
const response = await this.post(bodyJson, toolCallId, signal);
|
|
315210
315219
|
if (response.status !== 200) {
|
|
315211
315220
|
let detail = "";
|
|
315212
315221
|
try {
|
|
@@ -315216,8 +315225,9 @@ var init_blun_fetch_url = __esmMin((() => {
|
|
|
315216
315225
|
}
|
|
315217
315226
|
return response.text();
|
|
315218
315227
|
}
|
|
315219
|
-
async post(bodyJson, toolCallId) {
|
|
315228
|
+
async post(bodyJson, toolCallId, signal) {
|
|
315220
315229
|
const accessToken = await this.resolveApiKey();
|
|
315230
|
+
signal?.throwIfAborted();
|
|
315221
315231
|
return this.fetchImpl(this.baseUrl, {
|
|
315222
315232
|
method: "POST",
|
|
315223
315233
|
headers: {
|
|
@@ -315228,7 +315238,8 @@ var init_blun_fetch_url = __esmMin((() => {
|
|
|
315228
315238
|
...toolCallId !== void 0 && toolCallId.length > 0 ? { "X-Msh-Tool-Call-Id": toolCallId } : {},
|
|
315229
315239
|
...this.customHeaders
|
|
315230
315240
|
},
|
|
315231
|
-
body: bodyJson
|
|
315241
|
+
body: bodyJson,
|
|
315242
|
+
signal
|
|
315232
315243
|
});
|
|
315233
315244
|
}
|
|
315234
315245
|
async resolveApiKey() {
|
|
@@ -315272,20 +315283,26 @@ var init_blun_web_search = __esmMin((() => {
|
|
|
315272
315283
|
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
315273
315284
|
}
|
|
315274
315285
|
async search(query, options) {
|
|
315286
|
+
const signal = options?.signal;
|
|
315287
|
+
signal?.throwIfAborted();
|
|
315275
315288
|
const body = { text_query: query };
|
|
315276
315289
|
const bodyJson = JSON.stringify(body);
|
|
315277
315290
|
const toolCallId = options?.toolCallId;
|
|
315278
315291
|
const supportsNotices = typeof options?.onNotice === 'function';
|
|
315279
|
-
const response = await this.post(bodyJson, toolCallId, supportsNotices);
|
|
315292
|
+
const response = await this.post(bodyJson, toolCallId, supportsNotices, signal);
|
|
315293
|
+
signal?.throwIfAborted();
|
|
315280
315294
|
if (response.status === 401) {
|
|
315281
315295
|
const detail = await safeReadText(response);
|
|
315296
|
+
signal?.throwIfAborted();
|
|
315282
315297
|
throw new Error(`Blun search request failed: HTTP 401 (auth/unauthorized). ${detail}`.trim());
|
|
315283
315298
|
}
|
|
315284
315299
|
if (response.status !== 200) {
|
|
315285
315300
|
const detail = await safeReadText(response);
|
|
315301
|
+
signal?.throwIfAborted();
|
|
315286
315302
|
throw new Error(`Blun search request failed: HTTP ${String(response.status)}. ${detail}`.trim());
|
|
315287
315303
|
}
|
|
315288
315304
|
const json = (await response.json());
|
|
315305
|
+
signal?.throwIfAborted();
|
|
315289
315306
|
const raw = Array.isArray(json.search_results) ? json.search_results : [];
|
|
315290
315307
|
const status = json.search_status;
|
|
315291
315308
|
if (status !== undefined) {
|
|
@@ -315316,6 +315333,7 @@ var init_blun_web_search = __esmMin((() => {
|
|
|
315316
315333
|
options?.onNotice?.({ code: 'partial-sources', failedSources: status.failed_sources });
|
|
315317
315334
|
}
|
|
315318
315335
|
}
|
|
315336
|
+
signal?.throwIfAborted();
|
|
315319
315337
|
return raw.map((r) => {
|
|
315320
315338
|
const out = {
|
|
315321
315339
|
title: r.title ?? '',
|
|
@@ -315329,10 +315347,12 @@ var init_blun_web_search = __esmMin((() => {
|
|
|
315329
315347
|
return out;
|
|
315330
315348
|
});
|
|
315331
315349
|
}
|
|
315332
|
-
async post(bodyJson, toolCallId, supportsNotices) {
|
|
315350
|
+
async post(bodyJson, toolCallId, supportsNotices, signal) {
|
|
315333
315351
|
const accessToken = await this.resolveApiKey();
|
|
315352
|
+
signal?.throwIfAborted();
|
|
315334
315353
|
return this.fetchImpl(this.baseUrl, {
|
|
315335
315354
|
method: 'POST',
|
|
315355
|
+
signal,
|
|
315336
315356
|
headers: {
|
|
315337
315357
|
...this.defaultHeaders,
|
|
315338
315358
|
Authorization: `Bearer ${accessToken}`,
|