@blockrun/clawrouter 0.9.12 → 0.9.14
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/cli.js +42 -25
- package/dist/cli.js.map +1 -1
- package/dist/index.js +42 -25
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/scripts/reinstall.sh +17 -0
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/models.ts
|
|
2
2
|
var MODEL_ALIASES = {
|
|
3
|
-
// Claude
|
|
3
|
+
// Claude - short names
|
|
4
4
|
claude: "anthropic/claude-sonnet-4",
|
|
5
5
|
sonnet: "anthropic/claude-sonnet-4",
|
|
6
6
|
opus: "anthropic/claude-opus-4.6",
|
|
@@ -8,6 +8,11 @@ var MODEL_ALIASES = {
|
|
|
8
8
|
"opus-46": "anthropic/claude-opus-4.6",
|
|
9
9
|
"opus-45": "anthropic/claude-opus-4.5",
|
|
10
10
|
haiku: "anthropic/claude-haiku-4.5",
|
|
11
|
+
// Claude - provider/shortname patterns (common in agent frameworks)
|
|
12
|
+
"anthropic/sonnet": "anthropic/claude-sonnet-4",
|
|
13
|
+
"anthropic/opus": "anthropic/claude-opus-4.6",
|
|
14
|
+
"anthropic/haiku": "anthropic/claude-haiku-4.5",
|
|
15
|
+
"anthropic/claude": "anthropic/claude-sonnet-4",
|
|
11
16
|
// OpenAI
|
|
12
17
|
gpt: "openai/gpt-4o",
|
|
13
18
|
gpt4: "openai/gpt-4o",
|
|
@@ -2581,12 +2586,13 @@ var DEFAULT_COMPRESSION_CONFIG = {
|
|
|
2581
2586
|
// src/compression/layers/deduplication.ts
|
|
2582
2587
|
import crypto2 from "crypto";
|
|
2583
2588
|
function hashMessage(message) {
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
message.content
|
|
2587
|
-
|
|
2588
|
-
message.
|
|
2589
|
-
|
|
2589
|
+
let contentStr = "";
|
|
2590
|
+
if (typeof message.content === "string") {
|
|
2591
|
+
contentStr = message.content;
|
|
2592
|
+
} else if (Array.isArray(message.content)) {
|
|
2593
|
+
contentStr = JSON.stringify(message.content);
|
|
2594
|
+
}
|
|
2595
|
+
const parts = [message.role, contentStr, message.tool_call_id || "", message.name || ""];
|
|
2590
2596
|
if (message.tool_calls) {
|
|
2591
2597
|
parts.push(
|
|
2592
2598
|
JSON.stringify(
|
|
@@ -2649,13 +2655,13 @@ function deduplicateMessages(messages) {
|
|
|
2649
2655
|
|
|
2650
2656
|
// src/compression/layers/whitespace.ts
|
|
2651
2657
|
function normalizeWhitespace(content) {
|
|
2652
|
-
if (!content) return content;
|
|
2658
|
+
if (!content || typeof content !== "string") return content;
|
|
2653
2659
|
return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\n{3,}/g, "\n\n").replace(/[ \t]+$/gm, "").replace(/([^\n]) {2,}/g, "$1 ").replace(/^[ ]{8,}/gm, (match) => " ".repeat(Math.ceil(match.length / 4))).replace(/\t/g, " ").trim();
|
|
2654
2660
|
}
|
|
2655
2661
|
function normalizeMessagesWhitespace(messages) {
|
|
2656
2662
|
let charsSaved = 0;
|
|
2657
2663
|
const result = messages.map((message) => {
|
|
2658
|
-
if (!message.content) return message;
|
|
2664
|
+
if (!message.content || typeof message.content !== "string") return message;
|
|
2659
2665
|
const originalLength = message.content.length;
|
|
2660
2666
|
const normalizedContent = normalizeWhitespace(message.content);
|
|
2661
2667
|
charsSaved += originalLength - normalizedContent.length;
|
|
@@ -2759,6 +2765,9 @@ function generateCodebookHeader(usedCodes, pathMap = {}) {
|
|
|
2759
2765
|
|
|
2760
2766
|
// src/compression/layers/dictionary.ts
|
|
2761
2767
|
function encodeContent(content, inverseCodebook) {
|
|
2768
|
+
if (!content || typeof content !== "string") {
|
|
2769
|
+
return { encoded: content, substitutions: 0, codes: /* @__PURE__ */ new Set(), charsSaved: 0 };
|
|
2770
|
+
}
|
|
2762
2771
|
let encoded = content;
|
|
2763
2772
|
let substitutions = 0;
|
|
2764
2773
|
let charsSaved = 0;
|
|
@@ -2786,7 +2795,7 @@ function encodeMessages(messages) {
|
|
|
2786
2795
|
let totalCharsSaved = 0;
|
|
2787
2796
|
const allUsedCodes = /* @__PURE__ */ new Set();
|
|
2788
2797
|
const result = messages.map((message) => {
|
|
2789
|
-
if (!message.content) return message;
|
|
2798
|
+
if (!message.content || typeof message.content !== "string") return message;
|
|
2790
2799
|
const { encoded, substitutions, codes, charsSaved } = encodeContent(
|
|
2791
2800
|
message.content,
|
|
2792
2801
|
inverseCodebook
|
|
@@ -2812,7 +2821,7 @@ var PATH_REGEX = /(?:\/[\w.-]+){3,}/g;
|
|
|
2812
2821
|
function extractPaths(messages) {
|
|
2813
2822
|
const paths = [];
|
|
2814
2823
|
for (const message of messages) {
|
|
2815
|
-
if (!message.content) continue;
|
|
2824
|
+
if (!message.content || typeof message.content !== "string") continue;
|
|
2816
2825
|
const matches = message.content.match(PATH_REGEX);
|
|
2817
2826
|
if (matches) {
|
|
2818
2827
|
paths.push(...matches);
|
|
@@ -2854,7 +2863,7 @@ function shortenPaths(messages) {
|
|
|
2854
2863
|
});
|
|
2855
2864
|
let charsSaved = 0;
|
|
2856
2865
|
const result = messages.map((message) => {
|
|
2857
|
-
if (!message.content) return message;
|
|
2866
|
+
if (!message.content || typeof message.content !== "string") return message;
|
|
2858
2867
|
let content = message.content;
|
|
2859
2868
|
const originalLength = content.length;
|
|
2860
2869
|
for (const [code, prefix] of Object.entries(pathMap)) {
|
|
@@ -2905,7 +2914,7 @@ function compactMessagesJson(messages) {
|
|
|
2905
2914
|
const newLength = JSON.stringify(newMessage.tool_calls).length;
|
|
2906
2915
|
charsSaved += originalLength - newLength;
|
|
2907
2916
|
}
|
|
2908
|
-
if (message.role === "tool" && message.content && looksLikeJson(message.content)) {
|
|
2917
|
+
if (message.role === "tool" && message.content && typeof message.content === "string" && looksLikeJson(message.content)) {
|
|
2909
2918
|
const originalLength = message.content.length;
|
|
2910
2919
|
const compacted = compactJson(message.content);
|
|
2911
2920
|
charsSaved += originalLength - compacted.length;
|
|
@@ -2970,7 +2979,7 @@ function deduplicateLargeBlocks(messages) {
|
|
|
2970
2979
|
const blockHashes = /* @__PURE__ */ new Map();
|
|
2971
2980
|
let charsSaved = 0;
|
|
2972
2981
|
const result = messages.map((msg, idx) => {
|
|
2973
|
-
if (!msg.content || msg.content.length < 500) {
|
|
2982
|
+
if (!msg.content || typeof msg.content !== "string" || msg.content.length < 500) {
|
|
2974
2983
|
return msg;
|
|
2975
2984
|
}
|
|
2976
2985
|
const blockKey = msg.content.slice(0, 200);
|
|
@@ -2990,7 +2999,7 @@ function compressObservations(messages) {
|
|
|
2990
2999
|
let charsSaved = 0;
|
|
2991
3000
|
let observationsCompressed = 0;
|
|
2992
3001
|
let result = messages.map((msg) => {
|
|
2993
|
-
if (msg.role !== "tool" || !msg.content) {
|
|
3002
|
+
if (msg.role !== "tool" || !msg.content || typeof msg.content !== "string") {
|
|
2994
3003
|
return msg;
|
|
2995
3004
|
}
|
|
2996
3005
|
const original = msg.content;
|
|
@@ -3043,7 +3052,7 @@ function findRepeatedPhrases(allContent) {
|
|
|
3043
3052
|
function buildDynamicCodebook(messages) {
|
|
3044
3053
|
let allContent = "";
|
|
3045
3054
|
for (const msg of messages) {
|
|
3046
|
-
if (msg.content) {
|
|
3055
|
+
if (msg.content && typeof msg.content === "string") {
|
|
3047
3056
|
allContent += msg.content + "\n";
|
|
3048
3057
|
}
|
|
3049
3058
|
}
|
|
@@ -3068,6 +3077,7 @@ function buildDynamicCodebook(messages) {
|
|
|
3068
3077
|
return codebook;
|
|
3069
3078
|
}
|
|
3070
3079
|
function escapeRegex2(str) {
|
|
3080
|
+
if (!str || typeof str !== "string") return "";
|
|
3071
3081
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3072
3082
|
}
|
|
3073
3083
|
function applyDynamicCodebook(messages) {
|
|
@@ -3088,7 +3098,7 @@ function applyDynamicCodebook(messages) {
|
|
|
3088
3098
|
let charsSaved = 0;
|
|
3089
3099
|
let substitutions = 0;
|
|
3090
3100
|
const result = messages.map((msg) => {
|
|
3091
|
-
if (!msg.content) return msg;
|
|
3101
|
+
if (!msg.content || typeof msg.content !== "string") return msg;
|
|
3092
3102
|
let content = msg.content;
|
|
3093
3103
|
for (const phrase of sortedPhrases) {
|
|
3094
3104
|
const code = phraseToCode[phrase];
|
|
@@ -3121,7 +3131,12 @@ function generateDynamicCodebookHeader(codebook) {
|
|
|
3121
3131
|
// src/compression/index.ts
|
|
3122
3132
|
function calculateTotalChars(messages) {
|
|
3123
3133
|
return messages.reduce((total, msg) => {
|
|
3124
|
-
let chars =
|
|
3134
|
+
let chars = 0;
|
|
3135
|
+
if (typeof msg.content === "string") {
|
|
3136
|
+
chars = msg.content.length;
|
|
3137
|
+
} else if (Array.isArray(msg.content)) {
|
|
3138
|
+
chars = JSON.stringify(msg.content).length;
|
|
3139
|
+
}
|
|
3125
3140
|
if (msg.tool_calls) {
|
|
3126
3141
|
chars += JSON.stringify(msg.tool_calls).length;
|
|
3127
3142
|
}
|
|
@@ -3140,12 +3155,14 @@ function prependCodebookHeader(messages, usedCodes, pathMap) {
|
|
|
3140
3155
|
}
|
|
3141
3156
|
return messages.map((msg, i) => {
|
|
3142
3157
|
if (i === userIndex) {
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3158
|
+
if (typeof msg.content === "string") {
|
|
3159
|
+
return {
|
|
3160
|
+
...msg,
|
|
3161
|
+
content: `${header}
|
|
3146
3162
|
|
|
3147
|
-
${msg.content
|
|
3148
|
-
|
|
3163
|
+
${msg.content}`
|
|
3164
|
+
};
|
|
3165
|
+
}
|
|
3149
3166
|
}
|
|
3150
3167
|
return msg;
|
|
3151
3168
|
});
|
|
@@ -3250,11 +3267,11 @@ async function compressContext(messages, config = {}) {
|
|
|
3250
3267
|
const dynHeader = generateDynamicCodebookHeader(dynamicCodes);
|
|
3251
3268
|
if (dynHeader) {
|
|
3252
3269
|
const systemIndex = result.findIndex((m) => m.role === "system");
|
|
3253
|
-
if (systemIndex >= 0) {
|
|
3270
|
+
if (systemIndex >= 0 && typeof result[systemIndex].content === "string") {
|
|
3254
3271
|
result[systemIndex] = {
|
|
3255
3272
|
...result[systemIndex],
|
|
3256
3273
|
content: `${dynHeader}
|
|
3257
|
-
${result[systemIndex].content
|
|
3274
|
+
${result[systemIndex].content}`
|
|
3258
3275
|
};
|
|
3259
3276
|
}
|
|
3260
3277
|
}
|