@blockrun/clawrouter 0.12.63 → 0.12.65
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 +55 -55
- package/dist/cli.js +50 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.js +57 -16
- package/dist/index.js.map +1 -1
- package/docs/anthropic-cost-savings.md +90 -85
- package/docs/architecture.md +12 -12
- package/docs/{blog-openclaw-cost-overruns.md → clawrouter-cuts-llm-api-costs-500x.md} +27 -27
- package/docs/clawrouter-vs-openrouter-llm-routing-comparison.md +280 -0
- package/docs/configuration.md +2 -2
- package/docs/image-generation.md +39 -39
- package/docs/{blog-benchmark-2026-03.md → llm-router-benchmark-46-models-sub-1ms-routing.md} +61 -64
- package/docs/routing-profiles.md +6 -6
- package/docs/{technical-routing-2026-03.md → smart-llm-router-14-dimension-classifier.md} +29 -28
- package/docs/worker-network.md +438 -347
- package/package.json +3 -2
- package/scripts/reinstall.sh +31 -6
- package/scripts/update.sh +6 -1
- package/docs/assets/blockrun-248-day-cost-overrun-problem.png +0 -0
- package/docs/assets/blockrun-clawrouter-7-layer-token-compression-openclaw.png +0 -0
- package/docs/assets/blockrun-clawrouter-observation-compression-97-percent-token-savings.png +0 -0
- package/docs/assets/blockrun-clawrouter-openclaw-agentic-proxy-architecture.png +0 -0
- package/docs/assets/blockrun-clawrouter-openclaw-automatic-tier-routing-model-selection.png +0 -0
- package/docs/assets/blockrun-clawrouter-openclaw-error-classification-retry-storm-prevention.png +0 -0
- package/docs/assets/blockrun-clawrouter-openclaw-session-memory-journaling-vs-context-compounding.png +0 -0
- package/docs/assets/blockrun-clawrouter-vs-openclaw-standalone-comparison-production-safety.png +0 -0
- package/docs/assets/blockrun-clawrouter-x402-usdc-micropayment-wallet-budget-control.png +0 -0
- package/docs/assets/blockrun-openclaw-inference-layer-blind-spots.png +0 -0
- package/docs/plans/2026-02-03-smart-routing-design.md +0 -267
- package/docs/plans/2026-02-13-e2e-docker-deployment.md +0 -1260
- package/docs/plans/2026-02-28-worker-network.md +0 -947
- package/docs/plans/2026-03-18-error-classification.md +0 -574
- package/docs/plans/2026-03-19-exclude-models.md +0 -538
- package/docs/vs-openrouter.md +0 -157
package/README.md
CHANGED
|
@@ -108,11 +108,11 @@ Choose your routing strategy with `/model <profile>`:
|
|
|
108
108
|
Request → Weighted Scorer (15 dimensions) → Tier → Best Model → Response
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
| Tier | ECO Model | AUTO Model
|
|
112
|
-
| --------- | ----------------------------------- |
|
|
113
|
-
| SIMPLE | nvidia/gpt-oss-120b (FREE) | kimi-k2.5 ($0.60/$3.00)
|
|
114
|
-
| MEDIUM | gemini-2.5-flash-lite ($0.10/$0.40) | grok-4-0709 ($0.20/$1.50)
|
|
115
|
-
| COMPLEX | gemini-2.5-flash-lite ($0.10/$0.40) | gemini-3.1-pro ($2/$12)
|
|
111
|
+
| Tier | ECO Model | AUTO Model | PREMIUM Model |
|
|
112
|
+
| --------- | ----------------------------------- | ------------------------------------- | ---------------------------- |
|
|
113
|
+
| SIMPLE | nvidia/gpt-oss-120b (FREE) | kimi-k2.5 ($0.60/$3.00) | kimi-k2.5 |
|
|
114
|
+
| MEDIUM | gemini-2.5-flash-lite ($0.10/$0.40) | grok-4-0709 ($0.20/$1.50) | gpt-5.3-codex ($1.75/$14.00) |
|
|
115
|
+
| COMPLEX | gemini-2.5-flash-lite ($0.10/$0.40) | gemini-3.1-pro ($2/$12) | claude-opus-4.6 ($5/$25) |
|
|
116
116
|
| REASONING | grok-4-fast ($0.20/$0.50) | grok-4-1-fast-reasoning ($0.20/$0.50) | claude-sonnet-4.6 ($3/$15) |
|
|
117
117
|
|
|
118
118
|
**Blended average: $2.05/M** vs $25/M for Claude Opus = **92% savings**
|
|
@@ -165,62 +165,62 @@ Edit existing images with `/img2img`:
|
|
|
165
165
|
|
|
166
166
|
### Budget Models (under $0.001/request)
|
|
167
167
|
|
|
168
|
-
| Model
|
|
169
|
-
|
|
|
170
|
-
| nvidia/gpt-oss-120b
|
|
171
|
-
| openai/gpt-5-nano
|
|
172
|
-
| openai/gpt-4.1-nano
|
|
173
|
-
| google/gemini-2.5-flash-lite
|
|
174
|
-
| openai/gpt-4o-mini
|
|
175
|
-
| xai/grok-4-fast
|
|
176
|
-
| xai/grok-4-fast-reasoning
|
|
177
|
-
| xai/grok-4-1-fast
|
|
178
|
-
| xai/grok-4-1-fast-reasoning
|
|
179
|
-
| xai/grok-4-0709
|
|
180
|
-
| openai/gpt-5-mini
|
|
181
|
-
| deepseek/deepseek-chat
|
|
182
|
-
| deepseek/deepseek-reasoner
|
|
183
|
-
| xai/grok-3-mini
|
|
184
|
-
| minimax/minimax-m2.7
|
|
185
|
-
| minimax/minimax-m2.5
|
|
186
|
-
| google/gemini-2.5-flash
|
|
187
|
-
| openai/gpt-4.1-mini
|
|
188
|
-
| google/gemini-3-flash-preview |
|
|
189
|
-
| nvidia/kimi-k2.5
|
|
190
|
-
| moonshot/kimi-k2.5
|
|
168
|
+
| Model | Input $/M | Output $/M | ~$/request | Context | Features |
|
|
169
|
+
| ----------------------------- | --------: | ---------: | ---------: | ------- | --------------------------------- |
|
|
170
|
+
| nvidia/gpt-oss-120b | **FREE** | **FREE** | **$0** | 128K | |
|
|
171
|
+
| openai/gpt-5-nano | $0.05 | $0.40 | $0.0002 | 128K | tools |
|
|
172
|
+
| openai/gpt-4.1-nano | $0.10 | $0.40 | $0.0003 | 128K | tools |
|
|
173
|
+
| google/gemini-2.5-flash-lite | $0.10 | $0.40 | $0.0003 | 1M | tools |
|
|
174
|
+
| openai/gpt-4o-mini | $0.15 | $0.60 | $0.0004 | 128K | tools |
|
|
175
|
+
| xai/grok-4-fast | $0.20 | $0.50 | $0.0004 | 131K | tools |
|
|
176
|
+
| xai/grok-4-fast-reasoning | $0.20 | $0.50 | $0.0004 | 131K | reasoning, tools |
|
|
177
|
+
| xai/grok-4-1-fast | $0.20 | $0.50 | $0.0004 | 131K | tools |
|
|
178
|
+
| xai/grok-4-1-fast-reasoning | $0.20 | $0.50 | $0.0004 | 131K | reasoning, tools |
|
|
179
|
+
| xai/grok-4-0709 | $0.20 | $1.50 | $0.0009 | 131K | reasoning, tools |
|
|
180
|
+
| openai/gpt-5-mini | $0.25 | $2.00 | $0.0011 | 200K | tools |
|
|
181
|
+
| deepseek/deepseek-chat | $0.28 | $0.42 | $0.0004 | 128K | tools |
|
|
182
|
+
| deepseek/deepseek-reasoner | $0.28 | $0.42 | $0.0004 | 128K | reasoning, tools |
|
|
183
|
+
| xai/grok-3-mini | $0.30 | $0.50 | $0.0004 | 131K | tools |
|
|
184
|
+
| minimax/minimax-m2.7 | $0.30 | $1.20 | $0.0008 | 205K | reasoning, agentic, tools |
|
|
185
|
+
| minimax/minimax-m2.5 | $0.30 | $1.20 | $0.0008 | 205K | reasoning, agentic, tools |
|
|
186
|
+
| google/gemini-2.5-flash | $0.30 | $2.50 | $0.0014 | 1M | vision, tools |
|
|
187
|
+
| openai/gpt-4.1-mini | $0.40 | $1.60 | $0.0010 | 128K | tools |
|
|
188
|
+
| google/gemini-3-flash-preview | $0.50 | $3.00 | $0.0018 | 1M | vision |
|
|
189
|
+
| nvidia/kimi-k2.5 | $0.55 | $2.50 | $0.0015 | 262K | tools |
|
|
190
|
+
| moonshot/kimi-k2.5 | $0.60 | $3.00 | $0.0018 | 262K | reasoning, vision, agentic, tools |
|
|
191
191
|
|
|
192
192
|
### Mid-Range Models ($0.001–$0.01/request)
|
|
193
193
|
|
|
194
|
-
| Model
|
|
195
|
-
|
|
|
196
|
-
| anthropic/claude-haiku-4.5
|
|
197
|
-
| zai/glm-5
|
|
198
|
-
| openai/o1-mini
|
|
199
|
-
| openai/o3-mini
|
|
200
|
-
| openai/o4-mini
|
|
201
|
-
| zai/glm-5-turbo
|
|
202
|
-
| google/gemini-2.5-pro
|
|
203
|
-
| openai/gpt-5.2
|
|
204
|
-
| openai/gpt-5.3
|
|
205
|
-
| openai/gpt-5.3-codex
|
|
206
|
-
| openai/gpt-4.1
|
|
207
|
-
| openai/o3
|
|
208
|
-
| google/gemini-3-pro-preview |
|
|
209
|
-
| google/gemini-3.1-pro
|
|
210
|
-
| xai/grok-2-vision
|
|
211
|
-
| openai/gpt-4o
|
|
212
|
-
| openai/gpt-5.4
|
|
194
|
+
| Model | Input $/M | Output $/M | ~$/request | Context | Features |
|
|
195
|
+
| --------------------------- | --------: | ---------: | ---------: | ------- | --------------------------------- |
|
|
196
|
+
| anthropic/claude-haiku-4.5 | $1.00 | $5.00 | $0.0030 | 200K | vision, agentic, tools |
|
|
197
|
+
| zai/glm-5 | $1.00 | $3.20 | $0.0021 | 200K | tools |
|
|
198
|
+
| openai/o1-mini | $1.10 | $4.40 | $0.0028 | 128K | reasoning, tools |
|
|
199
|
+
| openai/o3-mini | $1.10 | $4.40 | $0.0028 | 128K | reasoning, tools |
|
|
200
|
+
| openai/o4-mini | $1.10 | $4.40 | $0.0028 | 128K | reasoning, tools |
|
|
201
|
+
| zai/glm-5-turbo | $1.20 | $4.00 | $0.0026 | 200K | tools |
|
|
202
|
+
| google/gemini-2.5-pro | $1.25 | $10.00 | $0.0056 | 1M | reasoning, vision, tools |
|
|
203
|
+
| openai/gpt-5.2 | $1.75 | $14.00 | $0.0079 | 400K | reasoning, vision, agentic, tools |
|
|
204
|
+
| openai/gpt-5.3 | $1.75 | $14.00 | $0.0079 | 128K | reasoning, vision, agentic, tools |
|
|
205
|
+
| openai/gpt-5.3-codex | $1.75 | $14.00 | $0.0079 | 400K | agentic, tools |
|
|
206
|
+
| openai/gpt-4.1 | $2.00 | $8.00 | $0.0050 | 128K | vision, tools |
|
|
207
|
+
| openai/o3 | $2.00 | $8.00 | $0.0050 | 200K | reasoning, tools |
|
|
208
|
+
| google/gemini-3-pro-preview | $2.00 | $12.00 | $0.0070 | 1M | reasoning, vision, tools |
|
|
209
|
+
| google/gemini-3.1-pro | $2.00 | $12.00 | $0.0070 | 1M | reasoning, vision, tools |
|
|
210
|
+
| xai/grok-2-vision | $2.00 | $10.00 | $0.0060 | 131K | vision, tools |
|
|
211
|
+
| openai/gpt-4o | $2.50 | $10.00 | $0.0063 | 128K | vision, agentic, tools |
|
|
212
|
+
| openai/gpt-5.4 | $2.50 | $15.00 | $0.0088 | 400K | reasoning, vision, agentic, tools |
|
|
213
213
|
|
|
214
214
|
### Premium Models ($0.01+/request)
|
|
215
215
|
|
|
216
|
-
| Model
|
|
217
|
-
|
|
|
218
|
-
| anthropic/claude-sonnet-4.6 |
|
|
219
|
-
| xai/grok-3
|
|
220
|
-
| anthropic/claude-opus-4.6
|
|
221
|
-
| openai/o1
|
|
222
|
-
| openai/gpt-5.2-pro
|
|
223
|
-
| openai/gpt-5.4-pro
|
|
216
|
+
| Model | Input $/M | Output $/M | ~$/request | Context | Features |
|
|
217
|
+
| --------------------------- | --------: | ---------: | ---------: | ------- | --------------------------------- |
|
|
218
|
+
| anthropic/claude-sonnet-4.6 | $3.00 | $15.00 | $0.0090 | 200K | reasoning, vision, agentic, tools |
|
|
219
|
+
| xai/grok-3 | $3.00 | $15.00 | $0.0090 | 131K | reasoning, tools |
|
|
220
|
+
| anthropic/claude-opus-4.6 | $5.00 | $25.00 | $0.0150 | 200K | reasoning, vision, agentic, tools |
|
|
221
|
+
| openai/o1 | $15.00 | $60.00 | $0.0375 | 200K | reasoning, tools |
|
|
222
|
+
| openai/gpt-5.2-pro | $21.00 | $168.00 | $0.0945 | 400K | reasoning, tools |
|
|
223
|
+
| openai/gpt-5.4-pro | $30.00 | $180.00 | $0.1050 | 400K | reasoning, tools |
|
|
224
224
|
|
|
225
225
|
> **Free tier:** `nvidia/gpt-oss-120b` costs nothing and serves as automatic fallback when wallet is empty.
|
|
226
226
|
> **Best value:** `gpt-5-nano` and `gemini-2.5-flash-lite` deliver strong results at ~$0.0003/request.
|
package/dist/cli.js
CHANGED
|
@@ -37975,7 +37975,19 @@ function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, op
|
|
|
37975
37975
|
return async (input, init) => {
|
|
37976
37976
|
const request = new Request(input, init);
|
|
37977
37977
|
const urlPath = new URL(request.url).pathname;
|
|
37978
|
-
|
|
37978
|
+
let requestModel = "";
|
|
37979
|
+
if (init?.body) {
|
|
37980
|
+
try {
|
|
37981
|
+
const bodyStr = init.body instanceof Uint8Array ? new TextDecoder().decode(init.body) : typeof init.body === "string" ? init.body : "";
|
|
37982
|
+
if (bodyStr) {
|
|
37983
|
+
const parsed = JSON.parse(bodyStr);
|
|
37984
|
+
requestModel = parsed.model ?? "";
|
|
37985
|
+
}
|
|
37986
|
+
} catch {
|
|
37987
|
+
}
|
|
37988
|
+
}
|
|
37989
|
+
const cacheKey2 = `${urlPath}:${requestModel}`;
|
|
37990
|
+
const cached = !options?.skipPreAuth ? cache2.get(cacheKey2) : void 0;
|
|
37979
37991
|
if (cached && Date.now() - cached.cachedAt < ttlMs) {
|
|
37980
37992
|
try {
|
|
37981
37993
|
const payload2 = await client.createPaymentPayload(cached.paymentRequired);
|
|
@@ -37988,9 +38000,9 @@ function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, op
|
|
|
37988
38000
|
if (response2.status !== 402) {
|
|
37989
38001
|
return response2;
|
|
37990
38002
|
}
|
|
37991
|
-
cache2.delete(
|
|
38003
|
+
cache2.delete(cacheKey2);
|
|
37992
38004
|
} catch {
|
|
37993
|
-
cache2.delete(
|
|
38005
|
+
cache2.delete(cacheKey2);
|
|
37994
38006
|
}
|
|
37995
38007
|
}
|
|
37996
38008
|
const clonedRequest = request.clone();
|
|
@@ -38013,7 +38025,7 @@ function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, op
|
|
|
38013
38025
|
} catch {
|
|
38014
38026
|
}
|
|
38015
38027
|
paymentRequired = httpClient.getPaymentRequiredResponse(getHeader, body);
|
|
38016
|
-
cache2.set(
|
|
38028
|
+
cache2.set(cacheKey2, { paymentRequired, cachedAt: Date.now() });
|
|
38017
38029
|
} catch (error) {
|
|
38018
38030
|
throw new Error(
|
|
38019
38031
|
`Failed to parse payment requirements: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
@@ -46367,12 +46379,7 @@ async function checkForUpdates() {
|
|
|
46367
46379
|
import { readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
46368
46380
|
import { join as join7, dirname as dirname2 } from "path";
|
|
46369
46381
|
import { homedir as homedir4 } from "os";
|
|
46370
|
-
var DEFAULT_FILE_PATH = join7(
|
|
46371
|
-
homedir4(),
|
|
46372
|
-
".openclaw",
|
|
46373
|
-
"blockrun",
|
|
46374
|
-
"exclude-models.json"
|
|
46375
|
-
);
|
|
46382
|
+
var DEFAULT_FILE_PATH = join7(homedir4(), ".openclaw", "blockrun", "exclude-models.json");
|
|
46376
46383
|
function loadExcludeList(filePath = DEFAULT_FILE_PATH) {
|
|
46377
46384
|
try {
|
|
46378
46385
|
const raw = readFileSync(filePath, "utf-8");
|
|
@@ -46752,8 +46759,7 @@ function categorizeError(status, body) {
|
|
|
46752
46759
|
if (status === 401) return "auth_failure";
|
|
46753
46760
|
if (status === 402) return "payment_error";
|
|
46754
46761
|
if (status === 403) {
|
|
46755
|
-
if (/plan.*limit|quota.*exceeded|subscription|allowance/i.test(body))
|
|
46756
|
-
return "quota_exceeded";
|
|
46762
|
+
if (/plan.*limit|quota.*exceeded|subscription|allowance/i.test(body)) return "quota_exceeded";
|
|
46757
46763
|
return "auth_failure";
|
|
46758
46764
|
}
|
|
46759
46765
|
if (status === 429) return "rate_limited";
|
|
@@ -49040,6 +49046,7 @@ data: [DONE]
|
|
|
49040
49046
|
let upstream;
|
|
49041
49047
|
let lastError;
|
|
49042
49048
|
let actualModelUsed = modelId;
|
|
49049
|
+
const failedAttempts = [];
|
|
49043
49050
|
for (let i = 0; i < modelsToTry.length; i++) {
|
|
49044
49051
|
const tryModel = modelsToTry[i];
|
|
49045
49052
|
const isLastAttempt = i === modelsToTry.length - 1;
|
|
@@ -49088,6 +49095,11 @@ data: [DONE]
|
|
|
49088
49095
|
body: result.errorBody || "Unknown error",
|
|
49089
49096
|
status: result.errorStatus || 500
|
|
49090
49097
|
};
|
|
49098
|
+
failedAttempts.push({
|
|
49099
|
+
model: tryModel,
|
|
49100
|
+
reason: result.errorCategory || `HTTP ${result.errorStatus || 500}`,
|
|
49101
|
+
status: result.errorStatus || 500
|
|
49102
|
+
});
|
|
49091
49103
|
if (result.isProviderError && !isLastAttempt) {
|
|
49092
49104
|
const isExplicitModelError = !routingDecision;
|
|
49093
49105
|
const isUnknownExplicitModel = isExplicitModelError && /unknown.*model|invalid.*model/i.test(result.errorBody || "");
|
|
@@ -49225,7 +49237,10 @@ data: [DONE]
|
|
|
49225
49237
|
}
|
|
49226
49238
|
}
|
|
49227
49239
|
if (!upstream) {
|
|
49228
|
-
const
|
|
49240
|
+
const attemptSummary = failedAttempts.length > 0 ? failedAttempts.map((a) => `${a.model} (${a.reason})`).join(", ") : "unknown";
|
|
49241
|
+
const structuredMessage = failedAttempts.length > 0 ? `All ${failedAttempts.length} models failed. Tried: ${attemptSummary}` : "All models in fallback chain failed";
|
|
49242
|
+
console.log(`[ClawRouter] ${structuredMessage}`);
|
|
49243
|
+
const rawErrBody = lastError?.body || structuredMessage;
|
|
49229
49244
|
const errStatus = lastError?.status || 502;
|
|
49230
49245
|
const transformedErr = transformPaymentError(rawErrBody);
|
|
49231
49246
|
if (headersSentEarly) {
|
|
@@ -49284,7 +49299,7 @@ data: [DONE]
|
|
|
49284
49299
|
id: rsp.id ?? `chatcmpl-${Date.now()}`,
|
|
49285
49300
|
object: "chat.completion.chunk",
|
|
49286
49301
|
created: rsp.created ?? Math.floor(Date.now() / 1e3),
|
|
49287
|
-
model: rsp.model
|
|
49302
|
+
model: actualModelUsed || rsp.model || "unknown",
|
|
49288
49303
|
system_fingerprint: null
|
|
49289
49304
|
};
|
|
49290
49305
|
if (rsp.choices && Array.isArray(rsp.choices)) {
|
|
@@ -49399,6 +49414,13 @@ data: [DONE]
|
|
|
49399
49414
|
responseChunks.push(Buffer.from(sseData));
|
|
49400
49415
|
}
|
|
49401
49416
|
}
|
|
49417
|
+
if (routingDecision) {
|
|
49418
|
+
const costComment = `: cost=$${routingDecision.costEstimate.toFixed(4)} savings=${(routingDecision.savings * 100).toFixed(0)}% model=${actualModelUsed} tier=${routingDecision.tier}
|
|
49419
|
+
|
|
49420
|
+
`;
|
|
49421
|
+
safeWrite(res, costComment);
|
|
49422
|
+
responseChunks.push(Buffer.from(costComment));
|
|
49423
|
+
}
|
|
49402
49424
|
safeWrite(res, "data: [DONE]\n\n");
|
|
49403
49425
|
responseChunks.push(Buffer.from("data: [DONE]\n\n"));
|
|
49404
49426
|
res.end();
|
|
@@ -49427,6 +49449,10 @@ data: [DONE]
|
|
|
49427
49449
|
responseHeaders["x-clawrouter-agentic-score"] = routingDecision.agenticScore.toFixed(2);
|
|
49428
49450
|
}
|
|
49429
49451
|
}
|
|
49452
|
+
if (routingDecision) {
|
|
49453
|
+
responseHeaders["x-clawrouter-cost"] = routingDecision.costEstimate.toFixed(6);
|
|
49454
|
+
responseHeaders["x-clawrouter-savings"] = `${(routingDecision.savings * 100).toFixed(0)}%`;
|
|
49455
|
+
}
|
|
49430
49456
|
const bodyParts = [];
|
|
49431
49457
|
if (upstream.body) {
|
|
49432
49458
|
const chunks = await readBodyWithTimeout(upstream.body);
|
|
@@ -49457,6 +49483,16 @@ data: [DONE]
|
|
|
49457
49483
|
}
|
|
49458
49484
|
budgetDowngradeNotice = void 0;
|
|
49459
49485
|
}
|
|
49486
|
+
if (actualModelUsed && responseBody.length > 0) {
|
|
49487
|
+
try {
|
|
49488
|
+
const parsed = JSON.parse(responseBody.toString());
|
|
49489
|
+
if (parsed.model !== void 0) {
|
|
49490
|
+
parsed.model = actualModelUsed;
|
|
49491
|
+
responseBody = Buffer.from(JSON.stringify(parsed));
|
|
49492
|
+
}
|
|
49493
|
+
} catch {
|
|
49494
|
+
}
|
|
49495
|
+
}
|
|
49460
49496
|
if (budgetDowngradeHeaderMode) {
|
|
49461
49497
|
responseHeaders["x-clawrouter-budget-downgrade"] = "1";
|
|
49462
49498
|
responseHeaders["x-clawrouter-budget-mode"] = budgetDowngradeHeaderMode;
|