@blockrun/clawrouter 0.9.3 → 0.9.5
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 +34 -23
- package/dist/cli.js +26 -49
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +10 -9
- package/dist/index.js +26 -49
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -509,8 +509,8 @@ type ProxyOptions = {
|
|
|
509
509
|
*/
|
|
510
510
|
sessionConfig?: Partial<SessionConfig>;
|
|
511
511
|
/**
|
|
512
|
-
* Auto-compress large requests to
|
|
513
|
-
* When enabled, requests
|
|
512
|
+
* Auto-compress large requests to reduce network usage.
|
|
513
|
+
* When enabled, requests are automatically compressed using
|
|
514
514
|
* LLM-safe context compression (15-40% reduction).
|
|
515
515
|
* Default: true
|
|
516
516
|
*/
|
|
@@ -521,11 +521,6 @@ type ProxyOptions = {
|
|
|
521
521
|
* Set to 0 to compress all requests.
|
|
522
522
|
*/
|
|
523
523
|
compressionThresholdKB?: number;
|
|
524
|
-
/**
|
|
525
|
-
* Maximum request size in KB after compression (default: 200).
|
|
526
|
-
* Hard limit enforced by BlockRun API.
|
|
527
|
-
*/
|
|
528
|
-
maxRequestSizeKB?: number;
|
|
529
524
|
onReady?: (port: number) => void;
|
|
530
525
|
onError?: (error: Error) => void;
|
|
531
526
|
onPayment?: (info: {
|
|
@@ -586,7 +581,12 @@ declare const blockrunProvider: ProviderPlugin;
|
|
|
586
581
|
declare const MODEL_ALIASES: Record<string, string>;
|
|
587
582
|
/**
|
|
588
583
|
* Resolve a model alias to its full model ID.
|
|
589
|
-
*
|
|
584
|
+
* Also strips "blockrun/" prefix for direct model paths.
|
|
585
|
+
* Examples:
|
|
586
|
+
* - "claude" -> "anthropic/claude-sonnet-4" (alias)
|
|
587
|
+
* - "blockrun/claude" -> "anthropic/claude-sonnet-4" (alias with prefix)
|
|
588
|
+
* - "blockrun/anthropic/claude-sonnet-4" -> "anthropic/claude-sonnet-4" (prefix stripped)
|
|
589
|
+
* - "openai/gpt-4o" -> "openai/gpt-4o" (unchanged)
|
|
590
590
|
*/
|
|
591
591
|
declare function resolveModelAlias(model: string): string;
|
|
592
592
|
type BlockRunModel = {
|
|
@@ -678,7 +678,8 @@ declare class RequestDeduplicator {
|
|
|
678
678
|
markInflight(key: string): void;
|
|
679
679
|
/** Complete an in-flight request — cache result and notify waiters. */
|
|
680
680
|
complete(key: string, result: CachedResponse): void;
|
|
681
|
-
/** Remove an in-flight entry on error (don't cache failures).
|
|
681
|
+
/** Remove an in-flight entry on error (don't cache failures).
|
|
682
|
+
* Also rejects any waiters so they can retry independently. */
|
|
682
683
|
removeInflight(key: string): void;
|
|
683
684
|
/** Prune expired completed entries. */
|
|
684
685
|
private prune;
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,7 @@ function resolveModelAlias(model) {
|
|
|
37
37
|
const withoutPrefix = normalized.slice("blockrun/".length);
|
|
38
38
|
const resolvedWithoutPrefix = MODEL_ALIASES[withoutPrefix];
|
|
39
39
|
if (resolvedWithoutPrefix) return resolvedWithoutPrefix;
|
|
40
|
+
return withoutPrefix;
|
|
40
41
|
}
|
|
41
42
|
return model;
|
|
42
43
|
}
|
|
@@ -2082,26 +2083,14 @@ var RequestDeduplicator = class {
|
|
|
2082
2083
|
getInflight(key) {
|
|
2083
2084
|
const entry = this.inflight.get(key);
|
|
2084
2085
|
if (!entry) return void 0;
|
|
2085
|
-
|
|
2086
|
-
entry.
|
|
2087
|
-
new Promise((r) => {
|
|
2088
|
-
const orig = entry.resolve;
|
|
2089
|
-
entry.resolve = (result) => {
|
|
2090
|
-
orig(result);
|
|
2091
|
-
resolve(result);
|
|
2092
|
-
r(result);
|
|
2093
|
-
};
|
|
2094
|
-
})
|
|
2095
|
-
);
|
|
2086
|
+
return new Promise((resolve) => {
|
|
2087
|
+
entry.resolvers.push(resolve);
|
|
2096
2088
|
});
|
|
2097
|
-
return promise;
|
|
2098
2089
|
}
|
|
2099
2090
|
/** Mark a request as in-flight. */
|
|
2100
2091
|
markInflight(key) {
|
|
2101
2092
|
this.inflight.set(key, {
|
|
2102
|
-
|
|
2103
|
-
},
|
|
2104
|
-
waiters: []
|
|
2093
|
+
resolvers: []
|
|
2105
2094
|
});
|
|
2106
2095
|
}
|
|
2107
2096
|
/** Complete an in-flight request — cache result and notify waiters. */
|
|
@@ -2111,14 +2100,33 @@ var RequestDeduplicator = class {
|
|
|
2111
2100
|
}
|
|
2112
2101
|
const entry = this.inflight.get(key);
|
|
2113
2102
|
if (entry) {
|
|
2114
|
-
entry.
|
|
2103
|
+
for (const resolve of entry.resolvers) {
|
|
2104
|
+
resolve(result);
|
|
2105
|
+
}
|
|
2115
2106
|
this.inflight.delete(key);
|
|
2116
2107
|
}
|
|
2117
2108
|
this.prune();
|
|
2118
2109
|
}
|
|
2119
|
-
/** Remove an in-flight entry on error (don't cache failures).
|
|
2110
|
+
/** Remove an in-flight entry on error (don't cache failures).
|
|
2111
|
+
* Also rejects any waiters so they can retry independently. */
|
|
2120
2112
|
removeInflight(key) {
|
|
2121
|
-
this.inflight.
|
|
2113
|
+
const entry = this.inflight.get(key);
|
|
2114
|
+
if (entry) {
|
|
2115
|
+
const errorBody = Buffer.from(
|
|
2116
|
+
JSON.stringify({
|
|
2117
|
+
error: { message: "Original request failed, please retry", type: "dedup_origin_failed" }
|
|
2118
|
+
})
|
|
2119
|
+
);
|
|
2120
|
+
for (const resolve of entry.resolvers) {
|
|
2121
|
+
resolve({
|
|
2122
|
+
status: 503,
|
|
2123
|
+
headers: { "content-type": "application/json" },
|
|
2124
|
+
body: errorBody,
|
|
2125
|
+
completedAt: Date.now()
|
|
2126
|
+
});
|
|
2127
|
+
}
|
|
2128
|
+
this.inflight.delete(key);
|
|
2129
|
+
}
|
|
2122
2130
|
}
|
|
2123
2131
|
/** Prune expired completed entries. */
|
|
2124
2132
|
prune() {
|
|
@@ -4026,7 +4034,6 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
4026
4034
|
}
|
|
4027
4035
|
const autoCompress = options.autoCompressRequests ?? true;
|
|
4028
4036
|
const compressionThreshold = options.compressionThresholdKB ?? 180;
|
|
4029
|
-
const sizeLimit = options.maxRequestSizeKB ?? 200;
|
|
4030
4037
|
const requestSizeKB = Math.ceil(body.length / 1024);
|
|
4031
4038
|
if (autoCompress && requestSizeKB > compressionThreshold) {
|
|
4032
4039
|
try {
|
|
@@ -4068,21 +4075,6 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
4068
4075
|
);
|
|
4069
4076
|
parsed.messages = compressionResult.messages;
|
|
4070
4077
|
body = Buffer.from(JSON.stringify(parsed));
|
|
4071
|
-
if (compressedSizeKB > sizeLimit) {
|
|
4072
|
-
const errorMsg = {
|
|
4073
|
-
error: {
|
|
4074
|
-
message: `Request size ${compressedSizeKB}KB still exceeds limit after compression (original: ${requestSizeKB}KB). Please reduce context size.`,
|
|
4075
|
-
type: "request_too_large",
|
|
4076
|
-
original_size_kb: requestSizeKB,
|
|
4077
|
-
compressed_size_kb: compressedSizeKB,
|
|
4078
|
-
limit_kb: sizeLimit,
|
|
4079
|
-
help: "Try: 1) Remove old messages from history, 2) Summarize large tool results, 3) Use direct API for very large contexts"
|
|
4080
|
-
}
|
|
4081
|
-
};
|
|
4082
|
-
res.writeHead(413, { "Content-Type": "application/json" });
|
|
4083
|
-
res.end(JSON.stringify(errorMsg));
|
|
4084
|
-
return;
|
|
4085
|
-
}
|
|
4086
4078
|
}
|
|
4087
4079
|
} catch (err) {
|
|
4088
4080
|
console.warn(
|
|
@@ -4090,21 +4082,6 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
4090
4082
|
);
|
|
4091
4083
|
}
|
|
4092
4084
|
}
|
|
4093
|
-
const finalSizeKB = Math.ceil(body.length / 1024);
|
|
4094
|
-
if (finalSizeKB > sizeLimit) {
|
|
4095
|
-
const errorMsg = {
|
|
4096
|
-
error: {
|
|
4097
|
-
message: `Request size ${finalSizeKB}KB exceeds limit ${sizeLimit}KB. Please reduce context size.`,
|
|
4098
|
-
type: "request_too_large",
|
|
4099
|
-
size_kb: finalSizeKB,
|
|
4100
|
-
limit_kb: sizeLimit,
|
|
4101
|
-
help: "Try: 1) Remove old messages from history, 2) Summarize large tool results, 3) Enable compression (autoCompressRequests: true)"
|
|
4102
|
-
}
|
|
4103
|
-
};
|
|
4104
|
-
res.writeHead(413, { "Content-Type": "application/json" });
|
|
4105
|
-
res.end(JSON.stringify(errorMsg));
|
|
4106
|
-
return;
|
|
4107
|
-
}
|
|
4108
4085
|
const dedupKey = RequestDeduplicator.hash(body);
|
|
4109
4086
|
const cached = deduplicator.getCached(dedupKey);
|
|
4110
4087
|
if (cached) {
|