@blockrun/clawrouter 0.9.0 → 0.9.2
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 +14 -12
- package/dist/cli.js +62 -61
- package/dist/cli.js.map +1 -1
- package/dist/index.js +84 -72
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2438,66 +2438,66 @@ function normalizeMessagesWhitespace(messages) {
|
|
|
2438
2438
|
// src/compression/codebook.ts
|
|
2439
2439
|
var STATIC_CODEBOOK = {
|
|
2440
2440
|
// High-impact: OpenClaw/Agent system prompt patterns (very common)
|
|
2441
|
-
|
|
2441
|
+
$OC01: "unbrowse_",
|
|
2442
2442
|
// Common prefix in tool names
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2443
|
+
$OC02: "<location>",
|
|
2444
|
+
$OC03: "</location>",
|
|
2445
|
+
$OC04: "<name>",
|
|
2446
|
+
$OC05: "</name>",
|
|
2447
|
+
$OC06: "<description>",
|
|
2448
|
+
$OC07: "</description>",
|
|
2449
|
+
$OC08: "(may need login)",
|
|
2450
|
+
$OC09: "API skill for OpenClaw",
|
|
2451
|
+
$OC10: "endpoints",
|
|
2452
2452
|
// Skill/tool markers
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2453
|
+
$SK01: "<available_skills>",
|
|
2454
|
+
$SK02: "</available_skills>",
|
|
2455
|
+
$SK03: "<skill>",
|
|
2456
|
+
$SK04: "</skill>",
|
|
2457
2457
|
// Schema patterns (very common in tool definitions)
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2458
|
+
$T01: 'type: "function"',
|
|
2459
|
+
$T02: '"type": "function"',
|
|
2460
|
+
$T03: '"type": "string"',
|
|
2461
|
+
$T04: '"type": "object"',
|
|
2462
|
+
$T05: '"type": "array"',
|
|
2463
|
+
$T06: '"type": "boolean"',
|
|
2464
|
+
$T07: '"type": "number"',
|
|
2465
2465
|
// Common descriptions
|
|
2466
|
-
|
|
2467
|
-
|
|
2466
|
+
$D01: "description:",
|
|
2467
|
+
$D02: '"description":',
|
|
2468
2468
|
// Common instructions
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2469
|
+
$I01: "You are a personal assistant",
|
|
2470
|
+
$I02: "Tool names are case-sensitive",
|
|
2471
|
+
$I03: "Call tools exactly as listed",
|
|
2472
|
+
$I04: "Use when",
|
|
2473
|
+
$I05: "without asking",
|
|
2474
2474
|
// Safety phrases
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2475
|
+
$S01: "Do not manipulate or persuade",
|
|
2476
|
+
$S02: "Prioritize safety and human oversight",
|
|
2477
|
+
$S03: "unless explicitly requested",
|
|
2478
2478
|
// JSON patterns
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2479
|
+
$J01: '"required": ["',
|
|
2480
|
+
$J02: '"properties": {',
|
|
2481
|
+
$J03: '"additionalProperties": false',
|
|
2482
2482
|
// Heartbeat patterns
|
|
2483
|
-
|
|
2484
|
-
|
|
2483
|
+
$H01: "HEARTBEAT_OK",
|
|
2484
|
+
$H02: "Read HEARTBEAT.md if it exists",
|
|
2485
2485
|
// Role markers
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2486
|
+
$R01: '"role": "system"',
|
|
2487
|
+
$R02: '"role": "user"',
|
|
2488
|
+
$R03: '"role": "assistant"',
|
|
2489
|
+
$R04: '"role": "tool"',
|
|
2490
2490
|
// Common endings/phrases
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2491
|
+
$E01: "would you like to",
|
|
2492
|
+
$E02: "Let me know if you",
|
|
2493
|
+
$E03: "internal APIs",
|
|
2494
|
+
$E04: "session cookies",
|
|
2495
2495
|
// BlockRun model aliases (common in prompts)
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2496
|
+
$M01: "blockrun/",
|
|
2497
|
+
$M02: "openai/",
|
|
2498
|
+
$M03: "anthropic/",
|
|
2499
|
+
$M04: "google/",
|
|
2500
|
+
$M05: "xai/"
|
|
2501
2501
|
};
|
|
2502
2502
|
function getInverseCodebook() {
|
|
2503
2503
|
const inverse = {};
|
|
@@ -2594,7 +2594,7 @@ function findFrequentPrefixes(paths) {
|
|
|
2594
2594
|
prefixCounts.set(prefix, (prefixCounts.get(prefix) || 0) + 1);
|
|
2595
2595
|
}
|
|
2596
2596
|
}
|
|
2597
|
-
return Array.from(prefixCounts.entries()).filter(([
|
|
2597
|
+
return Array.from(prefixCounts.entries()).filter(([, count]) => count >= 3).sort((a, b) => b[0].length - a[0].length).slice(0, 5).map(([prefix]) => prefix);
|
|
2598
2598
|
}
|
|
2599
2599
|
function shortenPaths(messages) {
|
|
2600
2600
|
const allPaths = extractPaths(messages);
|
|
@@ -2663,7 +2663,7 @@ function compactToolCalls(toolCalls) {
|
|
|
2663
2663
|
function compactMessagesJson(messages) {
|
|
2664
2664
|
let charsSaved = 0;
|
|
2665
2665
|
const result = messages.map((message) => {
|
|
2666
|
-
|
|
2666
|
+
const newMessage = { ...message };
|
|
2667
2667
|
if (message.tool_calls && message.tool_calls.length > 0) {
|
|
2668
2668
|
const originalLength = JSON.stringify(message.tool_calls).length;
|
|
2669
2669
|
newMessage.tool_calls = compactToolCalls(message.tool_calls);
|
|
@@ -2849,9 +2849,7 @@ function applyDynamicCodebook(messages) {
|
|
|
2849
2849
|
for (const [code, phrase] of Object.entries(codebook)) {
|
|
2850
2850
|
phraseToCode[phrase] = code;
|
|
2851
2851
|
}
|
|
2852
|
-
const sortedPhrases = Object.keys(phraseToCode).sort(
|
|
2853
|
-
(a, b) => b.length - a.length
|
|
2854
|
-
);
|
|
2852
|
+
const sortedPhrases = Object.keys(phraseToCode).sort((a, b) => b.length - a.length);
|
|
2855
2853
|
let charsSaved = 0;
|
|
2856
2854
|
let substitutions = 0;
|
|
2857
2855
|
const result = messages.map((msg) => {
|
|
@@ -2903,10 +2901,7 @@ function prependCodebookHeader(messages, usedCodes, pathMap) {
|
|
|
2903
2901
|
if (!header) return messages;
|
|
2904
2902
|
const userIndex = messages.findIndex((m) => m.role === "user");
|
|
2905
2903
|
if (userIndex === -1) {
|
|
2906
|
-
return [
|
|
2907
|
-
{ role: "system", content: header },
|
|
2908
|
-
...messages
|
|
2909
|
-
];
|
|
2904
|
+
return [{ role: "system", content: header }, ...messages];
|
|
2910
2905
|
}
|
|
2911
2906
|
return messages.map((msg, i) => {
|
|
2912
2907
|
if (i === userIndex) {
|
|
@@ -3997,7 +3992,9 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
3997
3992
|
const tools = parsed.tools;
|
|
3998
3993
|
const hasTools = Array.isArray(tools) && tools.length > 0;
|
|
3999
3994
|
if (hasTools) {
|
|
4000
|
-
console.log(
|
|
3995
|
+
console.log(
|
|
3996
|
+
`[ClawRouter] Tools detected (${tools.length}), agentic mode via keywords`
|
|
3997
|
+
);
|
|
4001
3998
|
}
|
|
4002
3999
|
routingDecision = route(prompt, systemPrompt, maxTokens, {
|
|
4003
4000
|
...routerOpts,
|
|
@@ -4031,7 +4028,9 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
4031
4028
|
const requestSizeKB = Math.ceil(body.length / 1024);
|
|
4032
4029
|
if (autoCompress && requestSizeKB > compressionThreshold) {
|
|
4033
4030
|
try {
|
|
4034
|
-
console.log(
|
|
4031
|
+
console.log(
|
|
4032
|
+
`[ClawRouter] Request size ${requestSizeKB}KB exceeds threshold ${compressionThreshold}KB, applying compression...`
|
|
4033
|
+
);
|
|
4035
4034
|
const parsed = JSON.parse(body.toString());
|
|
4036
4035
|
if (parsed.messages && parsed.messages.length > 0 && shouldCompress(parsed.messages)) {
|
|
4037
4036
|
const compressionResult = await compressContext(parsed.messages, {
|
|
@@ -4084,7 +4083,9 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
4084
4083
|
}
|
|
4085
4084
|
}
|
|
4086
4085
|
} catch (err) {
|
|
4087
|
-
console.warn(
|
|
4086
|
+
console.warn(
|
|
4087
|
+
`[ClawRouter] Compression failed: ${err instanceof Error ? err.message : String(err)}`
|
|
4088
|
+
);
|
|
4088
4089
|
}
|
|
4089
4090
|
}
|
|
4090
4091
|
const finalSizeKB = Math.ceil(body.length / 1024);
|
|
@@ -4561,7 +4562,15 @@ async function resolveOrGenerateWalletKey() {
|
|
|
4561
4562
|
}
|
|
4562
4563
|
|
|
4563
4564
|
// src/index.ts
|
|
4564
|
-
import {
|
|
4565
|
+
import {
|
|
4566
|
+
readFileSync,
|
|
4567
|
+
writeFileSync,
|
|
4568
|
+
existsSync,
|
|
4569
|
+
readdirSync,
|
|
4570
|
+
mkdirSync,
|
|
4571
|
+
copyFileSync,
|
|
4572
|
+
renameSync
|
|
4573
|
+
} from "fs";
|
|
4565
4574
|
import { homedir as homedir4 } from "os";
|
|
4566
4575
|
import { join as join5 } from "path";
|
|
4567
4576
|
import { privateKeyToAccount as privateKeyToAccount4 } from "viem/accounts";
|
|
@@ -4669,11 +4678,17 @@ function injectModelsConfig(logger) {
|
|
|
4669
4678
|
needsWrite = true;
|
|
4670
4679
|
}
|
|
4671
4680
|
} catch (err) {
|
|
4681
|
+
const backupPath = `${configPath}.backup.${Date.now()}`;
|
|
4682
|
+
try {
|
|
4683
|
+
copyFileSync(configPath, backupPath);
|
|
4684
|
+
logger.info(`Config parse failed, backed up to ${backupPath}`);
|
|
4685
|
+
} catch {
|
|
4686
|
+
logger.info("Config parse failed, could not create backup");
|
|
4687
|
+
}
|
|
4672
4688
|
logger.info(
|
|
4673
|
-
`
|
|
4689
|
+
`Skipping config injection (corrupt file): ${err instanceof Error ? err.message : String(err)}`
|
|
4674
4690
|
);
|
|
4675
|
-
|
|
4676
|
-
needsWrite = true;
|
|
4691
|
+
return;
|
|
4677
4692
|
}
|
|
4678
4693
|
} else {
|
|
4679
4694
|
logger.info("OpenClaw config not found, creating");
|
|
@@ -4765,12 +4780,7 @@ function injectModelsConfig(logger) {
|
|
|
4765
4780
|
{ id: "gemini", alias: "gemini" },
|
|
4766
4781
|
{ id: "flash", alias: "flash" }
|
|
4767
4782
|
];
|
|
4768
|
-
const DEPRECATED_ALIASES = [
|
|
4769
|
-
"blockrun/nvidia",
|
|
4770
|
-
"blockrun/gpt",
|
|
4771
|
-
"blockrun/o3",
|
|
4772
|
-
"blockrun/grok"
|
|
4773
|
-
];
|
|
4783
|
+
const DEPRECATED_ALIASES = ["blockrun/nvidia", "blockrun/gpt", "blockrun/o3", "blockrun/grok"];
|
|
4774
4784
|
if (!defaults.models) {
|
|
4775
4785
|
defaults.models = {};
|
|
4776
4786
|
needsWrite = true;
|
|
@@ -4792,7 +4802,9 @@ function injectModelsConfig(logger) {
|
|
|
4792
4802
|
}
|
|
4793
4803
|
if (needsWrite) {
|
|
4794
4804
|
try {
|
|
4795
|
-
|
|
4805
|
+
const tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
4806
|
+
writeFileSync(tmpPath, JSON.stringify(config, null, 2));
|
|
4807
|
+
renameSync(tmpPath, configPath);
|
|
4796
4808
|
logger.info("Smart routing enabled (blockrun/auto)");
|
|
4797
4809
|
} catch (err) {
|
|
4798
4810
|
logger.info(`Failed to write config: ${err instanceof Error ? err.message : String(err)}`);
|