@blockrun/clawrouter 0.9.3 → 0.9.4

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/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 fit within API limits.
513
- * When enabled, requests approaching 200KB are automatically compressed using
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: {
@@ -678,7 +673,8 @@ declare class RequestDeduplicator {
678
673
  markInflight(key: string): void;
679
674
  /** Complete an in-flight request — cache result and notify waiters. */
680
675
  complete(key: string, result: CachedResponse): void;
681
- /** Remove an in-flight entry on error (don't cache failures). */
676
+ /** Remove an in-flight entry on error (don't cache failures).
677
+ * Also rejects any waiters so they can retry independently. */
682
678
  removeInflight(key: string): void;
683
679
  /** Prune expired completed entries. */
684
680
  private prune;
package/dist/index.js CHANGED
@@ -2082,26 +2082,14 @@ var RequestDeduplicator = class {
2082
2082
  getInflight(key) {
2083
2083
  const entry = this.inflight.get(key);
2084
2084
  if (!entry) return void 0;
2085
- const promise = new Promise((resolve) => {
2086
- entry.waiters.push(
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
- );
2085
+ return new Promise((resolve) => {
2086
+ entry.resolvers.push(resolve);
2096
2087
  });
2097
- return promise;
2098
2088
  }
2099
2089
  /** Mark a request as in-flight. */
2100
2090
  markInflight(key) {
2101
2091
  this.inflight.set(key, {
2102
- resolve: () => {
2103
- },
2104
- waiters: []
2092
+ resolvers: []
2105
2093
  });
2106
2094
  }
2107
2095
  /** Complete an in-flight request — cache result and notify waiters. */
@@ -2111,14 +2099,31 @@ var RequestDeduplicator = class {
2111
2099
  }
2112
2100
  const entry = this.inflight.get(key);
2113
2101
  if (entry) {
2114
- entry.resolve(result);
2102
+ for (const resolve of entry.resolvers) {
2103
+ resolve(result);
2104
+ }
2115
2105
  this.inflight.delete(key);
2116
2106
  }
2117
2107
  this.prune();
2118
2108
  }
2119
- /** Remove an in-flight entry on error (don't cache failures). */
2109
+ /** Remove an in-flight entry on error (don't cache failures).
2110
+ * Also rejects any waiters so they can retry independently. */
2120
2111
  removeInflight(key) {
2121
- this.inflight.delete(key);
2112
+ const entry = this.inflight.get(key);
2113
+ if (entry) {
2114
+ const errorBody = Buffer.from(JSON.stringify({
2115
+ error: { message: "Original request failed, please retry", type: "dedup_origin_failed" }
2116
+ }));
2117
+ for (const resolve of entry.resolvers) {
2118
+ resolve({
2119
+ status: 503,
2120
+ headers: { "content-type": "application/json" },
2121
+ body: errorBody,
2122
+ completedAt: Date.now()
2123
+ });
2124
+ }
2125
+ this.inflight.delete(key);
2126
+ }
2122
2127
  }
2123
2128
  /** Prune expired completed entries. */
2124
2129
  prune() {
@@ -4026,7 +4031,6 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
4026
4031
  }
4027
4032
  const autoCompress = options.autoCompressRequests ?? true;
4028
4033
  const compressionThreshold = options.compressionThresholdKB ?? 180;
4029
- const sizeLimit = options.maxRequestSizeKB ?? 200;
4030
4034
  const requestSizeKB = Math.ceil(body.length / 1024);
4031
4035
  if (autoCompress && requestSizeKB > compressionThreshold) {
4032
4036
  try {
@@ -4068,21 +4072,6 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
4068
4072
  );
4069
4073
  parsed.messages = compressionResult.messages;
4070
4074
  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
4075
  }
4087
4076
  } catch (err) {
4088
4077
  console.warn(
@@ -4090,21 +4079,6 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
4090
4079
  );
4091
4080
  }
4092
4081
  }
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
4082
  const dedupKey = RequestDeduplicator.hash(body);
4109
4083
  const cached = deduplicator.getCached(dedupKey);
4110
4084
  if (cached) {