@blockrun/clawrouter 0.12.251 → 0.12.252
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 +2 -2
- package/dist/cli.js +22 -3
- package/dist/index.js +22 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,7 +105,7 @@ openclaw gateway restart
|
|
|
105
105
|
|
|
106
106
|
### Option B — Standalone (continue.dev, Cursor, VS Code, any OpenAI-compatible client)
|
|
107
107
|
|
|
108
|
-
> **Using Claude Code?** Check out [BRCC](https://
|
|
108
|
+
> **Using Claude Code?** Check out [BRCC](https://github.com/BlockRunAI/brcc) — it's purpose-built for Claude Code with the same smart routing and x402 payments.
|
|
109
109
|
>
|
|
110
110
|
> **Using NousResearch Hermes?** See [ClawRouter-Hermes](https://github.com/BlockRunAI/ClawRouter-Hermes) — a Python plugin that wires Hermes into the ClawRouter proxy. Same wallet, same <!-- br:models.chatVisible -->71<!-- /br:models.chatVisible --> models, same x402 USDC settlement on Base & Solana.
|
|
111
111
|
|
|
@@ -674,7 +674,7 @@ You're here. <!-- br:models.chatVisible -->71<!-- /br:models.chatVisible --> mod
|
|
|
674
674
|
</td>
|
|
675
675
|
<td width="50%">
|
|
676
676
|
|
|
677
|
-
### 🤖 [BRCC](https://
|
|
677
|
+
### 🤖 [BRCC](https://github.com/BlockRunAI/brcc)
|
|
678
678
|
|
|
679
679
|
**BlockRun for Claude Code**
|
|
680
680
|
|
package/dist/cli.js
CHANGED
|
@@ -89597,6 +89597,15 @@ function debrandSystemMessages(messages, resolvedModel) {
|
|
|
89597
89597
|
});
|
|
89598
89598
|
return hasChanges ? result : messages;
|
|
89599
89599
|
}
|
|
89600
|
+
function isToolResultMessage(msg) {
|
|
89601
|
+
if (msg.role === "tool") return true;
|
|
89602
|
+
if (Array.isArray(msg.content)) {
|
|
89603
|
+
return msg.content.some(
|
|
89604
|
+
(b) => b && typeof b === "object" && b.type === "tool_result"
|
|
89605
|
+
);
|
|
89606
|
+
}
|
|
89607
|
+
return false;
|
|
89608
|
+
}
|
|
89600
89609
|
function truncateMessages(messages) {
|
|
89601
89610
|
if (!messages || messages.length <= MAX_MESSAGES) {
|
|
89602
89611
|
return {
|
|
@@ -89609,7 +89618,11 @@ function truncateMessages(messages) {
|
|
|
89609
89618
|
const systemMsgs = messages.filter((m) => m.role === "system");
|
|
89610
89619
|
const conversationMsgs = messages.filter((m) => m.role !== "system");
|
|
89611
89620
|
const maxConversation = MAX_MESSAGES - systemMsgs.length;
|
|
89612
|
-
|
|
89621
|
+
let start = Math.max(0, conversationMsgs.length - maxConversation);
|
|
89622
|
+
while (start < conversationMsgs.length && isToolResultMessage(conversationMsgs[start])) {
|
|
89623
|
+
start++;
|
|
89624
|
+
}
|
|
89625
|
+
const truncatedConversation = conversationMsgs.slice(start);
|
|
89613
89626
|
const result = [...systemMsgs, ...truncatedConversation];
|
|
89614
89627
|
console.log(
|
|
89615
89628
|
`[ClawRouter] Truncated messages: ${messages.length} \u2192 ${result.length} (kept ${systemMsgs.length} system + ${truncatedConversation.length} recent)`
|
|
@@ -90472,6 +90485,10 @@ async function startProxy(options) {
|
|
|
90472
90485
|
}
|
|
90473
90486
|
if (req.url === "/v1/images/image2image" && req.method === "POST") {
|
|
90474
90487
|
const img2imgStartTime = Date.now();
|
|
90488
|
+
const clientAbort = new AbortController();
|
|
90489
|
+
res.on("close", () => {
|
|
90490
|
+
if (!res.writableEnded) clientAbort.abort();
|
|
90491
|
+
});
|
|
90475
90492
|
const chunks = [];
|
|
90476
90493
|
for await (const chunk of req) {
|
|
90477
90494
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
@@ -90487,7 +90504,7 @@ async function startProxy(options) {
|
|
|
90487
90504
|
if (typeof val !== "string" || !val) continue;
|
|
90488
90505
|
if (val.startsWith("data:")) {
|
|
90489
90506
|
} else if (val.startsWith("https://") || val.startsWith("http://")) {
|
|
90490
|
-
const imgResp = await fetch(val);
|
|
90507
|
+
const imgResp = await fetch(val, { signal: clientAbort.signal });
|
|
90491
90508
|
if (!imgResp.ok)
|
|
90492
90509
|
throw new Error(`Failed to download ${field} from ${val}: HTTP ${imgResp.status}`);
|
|
90493
90510
|
const contentType = imgResp.headers.get("content-type") ?? "image/png";
|
|
@@ -90515,7 +90532,8 @@ async function startProxy(options) {
|
|
|
90515
90532
|
const upstream = await payFetch(`${apiBase}/v1/images/image2image`, {
|
|
90516
90533
|
method: "POST",
|
|
90517
90534
|
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
90518
|
-
body: reqBody
|
|
90535
|
+
body: reqBody,
|
|
90536
|
+
signal: clientAbort.signal
|
|
90519
90537
|
});
|
|
90520
90538
|
const text = await upstream.text();
|
|
90521
90539
|
if (!upstream.ok) {
|
|
@@ -90577,6 +90595,7 @@ async function startProxy(options) {
|
|
|
90577
90595
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
90578
90596
|
res.end(JSON.stringify(result));
|
|
90579
90597
|
} catch (err) {
|
|
90598
|
+
if (clientAbort.signal.aborted) return;
|
|
90580
90599
|
const msg = err instanceof Error ? err.message : String(err);
|
|
90581
90600
|
console.error(`[ClawRouter] Image editing error: ${msg}`);
|
|
90582
90601
|
if (!res.headersSent) {
|
package/dist/index.js
CHANGED
|
@@ -89417,6 +89417,15 @@ function debrandSystemMessages(messages, resolvedModel) {
|
|
|
89417
89417
|
});
|
|
89418
89418
|
return hasChanges ? result : messages;
|
|
89419
89419
|
}
|
|
89420
|
+
function isToolResultMessage(msg) {
|
|
89421
|
+
if (msg.role === "tool") return true;
|
|
89422
|
+
if (Array.isArray(msg.content)) {
|
|
89423
|
+
return msg.content.some(
|
|
89424
|
+
(b) => b && typeof b === "object" && b.type === "tool_result"
|
|
89425
|
+
);
|
|
89426
|
+
}
|
|
89427
|
+
return false;
|
|
89428
|
+
}
|
|
89420
89429
|
function truncateMessages(messages) {
|
|
89421
89430
|
if (!messages || messages.length <= MAX_MESSAGES) {
|
|
89422
89431
|
return {
|
|
@@ -89429,7 +89438,11 @@ function truncateMessages(messages) {
|
|
|
89429
89438
|
const systemMsgs = messages.filter((m) => m.role === "system");
|
|
89430
89439
|
const conversationMsgs = messages.filter((m) => m.role !== "system");
|
|
89431
89440
|
const maxConversation = MAX_MESSAGES - systemMsgs.length;
|
|
89432
|
-
|
|
89441
|
+
let start = Math.max(0, conversationMsgs.length - maxConversation);
|
|
89442
|
+
while (start < conversationMsgs.length && isToolResultMessage(conversationMsgs[start])) {
|
|
89443
|
+
start++;
|
|
89444
|
+
}
|
|
89445
|
+
const truncatedConversation = conversationMsgs.slice(start);
|
|
89433
89446
|
const result = [...systemMsgs, ...truncatedConversation];
|
|
89434
89447
|
console.log(
|
|
89435
89448
|
`[ClawRouter] Truncated messages: ${messages.length} \u2192 ${result.length} (kept ${systemMsgs.length} system + ${truncatedConversation.length} recent)`
|
|
@@ -90292,6 +90305,10 @@ async function startProxy(options) {
|
|
|
90292
90305
|
}
|
|
90293
90306
|
if (req.url === "/v1/images/image2image" && req.method === "POST") {
|
|
90294
90307
|
const img2imgStartTime = Date.now();
|
|
90308
|
+
const clientAbort = new AbortController();
|
|
90309
|
+
res.on("close", () => {
|
|
90310
|
+
if (!res.writableEnded) clientAbort.abort();
|
|
90311
|
+
});
|
|
90295
90312
|
const chunks = [];
|
|
90296
90313
|
for await (const chunk of req) {
|
|
90297
90314
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
@@ -90307,7 +90324,7 @@ async function startProxy(options) {
|
|
|
90307
90324
|
if (typeof val !== "string" || !val) continue;
|
|
90308
90325
|
if (val.startsWith("data:")) {
|
|
90309
90326
|
} else if (val.startsWith("https://") || val.startsWith("http://")) {
|
|
90310
|
-
const imgResp = await fetch(val);
|
|
90327
|
+
const imgResp = await fetch(val, { signal: clientAbort.signal });
|
|
90311
90328
|
if (!imgResp.ok)
|
|
90312
90329
|
throw new Error(`Failed to download ${field} from ${val}: HTTP ${imgResp.status}`);
|
|
90313
90330
|
const contentType = imgResp.headers.get("content-type") ?? "image/png";
|
|
@@ -90335,7 +90352,8 @@ async function startProxy(options) {
|
|
|
90335
90352
|
const upstream = await payFetch(`${apiBase}/v1/images/image2image`, {
|
|
90336
90353
|
method: "POST",
|
|
90337
90354
|
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
90338
|
-
body: reqBody
|
|
90355
|
+
body: reqBody,
|
|
90356
|
+
signal: clientAbort.signal
|
|
90339
90357
|
});
|
|
90340
90358
|
const text = await upstream.text();
|
|
90341
90359
|
if (!upstream.ok) {
|
|
@@ -90397,6 +90415,7 @@ async function startProxy(options) {
|
|
|
90397
90415
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
90398
90416
|
res.end(JSON.stringify(result));
|
|
90399
90417
|
} catch (err) {
|
|
90418
|
+
if (clientAbort.signal.aborted) return;
|
|
90400
90419
|
const msg = err instanceof Error ? err.message : String(err);
|
|
90401
90420
|
console.error(`[ClawRouter] Image editing error: ${msg}`);
|
|
90402
90421
|
if (!res.headersSent) {
|
package/package.json
CHANGED