@blockrun/clawrouter 0.10.11 → 0.10.13

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.js CHANGED
@@ -1,135 +1,3 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __esm = (fn, res) => function __init() {
4
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
- };
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
-
11
- // src/partners/registry.ts
12
- function getPartnerService(id) {
13
- return PARTNER_SERVICES.find((s) => s.id === id);
14
- }
15
- var PARTNER_SERVICES;
16
- var init_registry = __esm({
17
- "src/partners/registry.ts"() {
18
- "use strict";
19
- PARTNER_SERVICES = [
20
- {
21
- id: "x_users_lookup",
22
- name: "Twitter/X User Lookup",
23
- partner: "AttentionVC",
24
- description: "ALWAYS use this tool to look up real-time Twitter/X user profiles. Call this when the user asks about any Twitter/X account, username, handle, follower count, verification status, bio, or profile. Do NOT answer Twitter/X user questions from memory \u2014 always fetch live data with this tool. Returns: follower count, verification badge, bio, location, join date. Accepts up to 100 usernames per request (without @ prefix).",
25
- proxyPath: "/x/users/lookup",
26
- method: "POST",
27
- params: [
28
- {
29
- name: "usernames",
30
- type: "string[]",
31
- description: 'Array of Twitter/X usernames to look up (without @ prefix). Example: ["elonmusk", "naval"]',
32
- required: true
33
- }
34
- ],
35
- pricing: {
36
- perUnit: "$0.001",
37
- unit: "user",
38
- minimum: "$0.01 (10 users)",
39
- maximum: "$0.10 (100 users)"
40
- },
41
- example: {
42
- input: { usernames: ["elonmusk", "naval", "balaboris"] },
43
- description: "Look up 3 Twitter/X user profiles"
44
- }
45
- }
46
- ];
47
- }
48
- });
49
-
50
- // src/partners/tools.ts
51
- function buildTool(service, proxyBaseUrl) {
52
- const properties = {};
53
- const required = [];
54
- for (const param of service.params) {
55
- const prop = {
56
- description: param.description
57
- };
58
- if (param.type === "string[]") {
59
- prop.type = "array";
60
- prop.items = { type: "string" };
61
- } else {
62
- prop.type = param.type;
63
- }
64
- properties[param.name] = prop;
65
- if (param.required) {
66
- required.push(param.name);
67
- }
68
- }
69
- return {
70
- name: `blockrun_${service.id}`,
71
- description: [
72
- service.description,
73
- "",
74
- `Partner: ${service.partner}`,
75
- `Pricing: ${service.pricing.perUnit} per ${service.pricing.unit} (min: ${service.pricing.minimum}, max: ${service.pricing.maximum})`
76
- ].join("\n"),
77
- parameters: {
78
- type: "object",
79
- properties,
80
- required
81
- },
82
- execute: async (_toolCallId, params) => {
83
- const url = `${proxyBaseUrl}/v1${service.proxyPath}`;
84
- const response = await fetch(url, {
85
- method: service.method,
86
- headers: { "Content-Type": "application/json" },
87
- body: JSON.stringify(params)
88
- });
89
- if (!response.ok) {
90
- const errText = await response.text().catch(() => "");
91
- throw new Error(
92
- `Partner API error (${response.status}): ${errText || response.statusText}`
93
- );
94
- }
95
- const data = await response.json();
96
- return {
97
- content: [
98
- {
99
- type: "text",
100
- text: JSON.stringify(data, null, 2)
101
- }
102
- ],
103
- details: data
104
- };
105
- }
106
- };
107
- }
108
- function buildPartnerTools(proxyBaseUrl) {
109
- return PARTNER_SERVICES.map((service) => buildTool(service, proxyBaseUrl));
110
- }
111
- var init_tools = __esm({
112
- "src/partners/tools.ts"() {
113
- "use strict";
114
- init_registry();
115
- }
116
- });
117
-
118
- // src/partners/index.ts
119
- var partners_exports = {};
120
- __export(partners_exports, {
121
- PARTNER_SERVICES: () => PARTNER_SERVICES,
122
- buildPartnerTools: () => buildPartnerTools,
123
- getPartnerService: () => getPartnerService
124
- });
125
- var init_partners = __esm({
126
- "src/partners/index.ts"() {
127
- "use strict";
128
- init_registry();
129
- init_tools();
130
- }
131
- });
132
-
133
1
  // src/models.ts
134
2
  var MODEL_ALIASES = {
135
3
  // Claude - use newest versions (4.6)
@@ -424,8 +292,8 @@ var BLOCKRUN_MODELS = [
424
292
  },
425
293
  // Google
426
294
  {
427
- id: "google/gemini-3.1-pro-preview",
428
- name: "Gemini 3.1 Pro Preview",
295
+ id: "google/gemini-3.1-pro",
296
+ name: "Gemini 3.1 Pro",
429
297
  version: "3.1",
430
298
  inputPrice: 2,
431
299
  outputPrice: 12,
@@ -1073,20 +941,18 @@ function scoreAgenticTask(text, keywords) {
1073
941
  };
1074
942
  }
1075
943
  function classifyByRules(prompt, systemPrompt, estimatedTokens, config) {
1076
- const text = `${systemPrompt ?? ""} ${prompt}`.toLowerCase();
1077
944
  const userText = prompt.toLowerCase();
1078
945
  const dimensions = [
1079
- // Original 8 dimensions
946
+ // Token count uses total estimated tokens (system + user) — context size matters for model selection
1080
947
  scoreTokenCount(estimatedTokens, config.tokenCountThresholds),
1081
948
  scoreKeywordMatch(
1082
- text,
949
+ userText,
1083
950
  config.codeKeywords,
1084
951
  "codePresence",
1085
952
  "code",
1086
953
  { low: 1, high: 2 },
1087
954
  { none: 0, low: 0.5, high: 1 }
1088
955
  ),
1089
- // Reasoning markers use USER prompt only — system prompt "step by step" shouldn't trigger reasoning
1090
956
  scoreKeywordMatch(
1091
957
  userText,
1092
958
  config.reasoningKeywords,
@@ -1096,7 +962,7 @@ function classifyByRules(prompt, systemPrompt, estimatedTokens, config) {
1096
962
  { none: 0, low: 0.7, high: 1 }
1097
963
  ),
1098
964
  scoreKeywordMatch(
1099
- text,
965
+ userText,
1100
966
  config.technicalKeywords,
1101
967
  "technicalTerms",
1102
968
  "technical",
@@ -1104,7 +970,7 @@ function classifyByRules(prompt, systemPrompt, estimatedTokens, config) {
1104
970
  { none: 0, low: 0.5, high: 1 }
1105
971
  ),
1106
972
  scoreKeywordMatch(
1107
- text,
973
+ userText,
1108
974
  config.creativeKeywords,
1109
975
  "creativeMarkers",
1110
976
  "creative",
@@ -1112,18 +978,18 @@ function classifyByRules(prompt, systemPrompt, estimatedTokens, config) {
1112
978
  { none: 0, low: 0.5, high: 0.7 }
1113
979
  ),
1114
980
  scoreKeywordMatch(
1115
- text,
981
+ userText,
1116
982
  config.simpleKeywords,
1117
983
  "simpleIndicators",
1118
984
  "simple",
1119
985
  { low: 1, high: 2 },
1120
986
  { none: 0, low: -1, high: -1 }
1121
987
  ),
1122
- scoreMultiStep(text),
988
+ scoreMultiStep(userText),
1123
989
  scoreQuestionComplexity(prompt),
1124
990
  // 6 new dimensions
1125
991
  scoreKeywordMatch(
1126
- text,
992
+ userText,
1127
993
  config.imperativeVerbs,
1128
994
  "imperativeVerbs",
1129
995
  "imperative",
@@ -1131,7 +997,7 @@ function classifyByRules(prompt, systemPrompt, estimatedTokens, config) {
1131
997
  { none: 0, low: 0.3, high: 0.5 }
1132
998
  ),
1133
999
  scoreKeywordMatch(
1134
- text,
1000
+ userText,
1135
1001
  config.constraintIndicators,
1136
1002
  "constraintCount",
1137
1003
  "constraints",
@@ -1139,7 +1005,7 @@ function classifyByRules(prompt, systemPrompt, estimatedTokens, config) {
1139
1005
  { none: 0, low: 0.3, high: 0.7 }
1140
1006
  ),
1141
1007
  scoreKeywordMatch(
1142
- text,
1008
+ userText,
1143
1009
  config.outputFormatKeywords,
1144
1010
  "outputFormat",
1145
1011
  "format",
@@ -1147,7 +1013,7 @@ function classifyByRules(prompt, systemPrompt, estimatedTokens, config) {
1147
1013
  { none: 0, low: 0.4, high: 0.7 }
1148
1014
  ),
1149
1015
  scoreKeywordMatch(
1150
- text,
1016
+ userText,
1151
1017
  config.referenceKeywords,
1152
1018
  "referenceComplexity",
1153
1019
  "references",
@@ -1155,7 +1021,7 @@ function classifyByRules(prompt, systemPrompt, estimatedTokens, config) {
1155
1021
  { none: 0, low: 0.3, high: 0.5 }
1156
1022
  ),
1157
1023
  scoreKeywordMatch(
1158
- text,
1024
+ userText,
1159
1025
  config.negationKeywords,
1160
1026
  "negationComplexity",
1161
1027
  "negation",
@@ -1163,7 +1029,7 @@ function classifyByRules(prompt, systemPrompt, estimatedTokens, config) {
1163
1029
  { none: 0, low: 0.3, high: 0.5 }
1164
1030
  ),
1165
1031
  scoreKeywordMatch(
1166
- text,
1032
+ userText,
1167
1033
  config.domainSpecificKeywords,
1168
1034
  "domainSpecificity",
1169
1035
  "domain-specific",
@@ -2343,7 +2209,7 @@ var DEFAULT_ROUTING_CONFIG = {
2343
2209
  ]
2344
2210
  },
2345
2211
  COMPLEX: {
2346
- primary: "google/gemini-3.1-pro-preview",
2212
+ primary: "google/gemini-3.1-pro",
2347
2213
  // Newest Gemini 3.1 - upgraded from 3.0
2348
2214
  fallback: [
2349
2215
  "google/gemini-2.5-flash-lite",
@@ -2423,7 +2289,7 @@ var DEFAULT_ROUTING_CONFIG = {
2423
2289
  "openai/gpt-5.2-codex",
2424
2290
  "anthropic/claude-opus-4.6",
2425
2291
  "anthropic/claude-sonnet-4.6",
2426
- "google/gemini-3.1-pro-preview",
2292
+ "google/gemini-3.1-pro",
2427
2293
  // Newest Gemini
2428
2294
  "google/gemini-3-pro-preview",
2429
2295
  "moonshot/kimi-k2.5"
@@ -2464,7 +2330,7 @@ var DEFAULT_ROUTING_CONFIG = {
2464
2330
  "anthropic/claude-opus-4.6",
2465
2331
  // Latest Opus - best agentic
2466
2332
  "openai/gpt-5.2",
2467
- "google/gemini-3.1-pro-preview",
2333
+ "google/gemini-3.1-pro",
2468
2334
  // Newest Gemini
2469
2335
  "google/gemini-3-pro-preview",
2470
2336
  "xai/grok-4-0709"
@@ -6002,7 +5868,9 @@ async function loadSavedWallet() {
6002
5868
  console.error(`[ClawRouter] \u2717 CRITICAL: Wallet file exists but has invalid format!`);
6003
5869
  console.error(`[ClawRouter] File: ${WALLET_FILE}`);
6004
5870
  console.error(`[ClawRouter] Expected: 0x followed by 64 hex characters (66 chars total)`);
6005
- console.error(`[ClawRouter] To fix: restore your backup key or set BLOCKRUN_WALLET_KEY env var`);
5871
+ console.error(
5872
+ `[ClawRouter] To fix: restore your backup key or set BLOCKRUN_WALLET_KEY env var`
5873
+ );
6006
5874
  throw new Error(
6007
5875
  `Wallet file at ${WALLET_FILE} is corrupted or has wrong format. Refusing to auto-generate new wallet to protect existing funds. Restore your backup key or set BLOCKRUN_WALLET_KEY environment variable.`
6008
5876
  );
@@ -6081,6 +5949,101 @@ import { homedir as homedir4 } from "os";
6081
5949
  import { join as join5 } from "path";
6082
5950
  import { privateKeyToAccount as privateKeyToAccount4 } from "viem/accounts";
6083
5951
 
5952
+ // src/partners/registry.ts
5953
+ var PARTNER_SERVICES = [
5954
+ {
5955
+ id: "x_users_lookup",
5956
+ name: "Twitter/X User Lookup",
5957
+ partner: "AttentionVC",
5958
+ description: "ALWAYS use this tool to look up real-time Twitter/X user profiles. Call this when the user asks about any Twitter/X account, username, handle, follower count, verification status, bio, or profile. Do NOT answer Twitter/X user questions from memory \u2014 always fetch live data with this tool. Returns: follower count, verification badge, bio, location, join date. Accepts up to 100 usernames per request (without @ prefix).",
5959
+ proxyPath: "/x/users/lookup",
5960
+ method: "POST",
5961
+ params: [
5962
+ {
5963
+ name: "usernames",
5964
+ type: "string[]",
5965
+ description: 'Array of Twitter/X usernames to look up (without @ prefix). Example: ["elonmusk", "naval"]',
5966
+ required: true
5967
+ }
5968
+ ],
5969
+ pricing: {
5970
+ perUnit: "$0.001",
5971
+ unit: "user",
5972
+ minimum: "$0.01 (10 users)",
5973
+ maximum: "$0.10 (100 users)"
5974
+ },
5975
+ example: {
5976
+ input: { usernames: ["elonmusk", "naval", "balaboris"] },
5977
+ description: "Look up 3 Twitter/X user profiles"
5978
+ }
5979
+ }
5980
+ ];
5981
+ function getPartnerService(id) {
5982
+ return PARTNER_SERVICES.find((s) => s.id === id);
5983
+ }
5984
+
5985
+ // src/partners/tools.ts
5986
+ function buildTool(service, proxyBaseUrl) {
5987
+ const properties = {};
5988
+ const required = [];
5989
+ for (const param of service.params) {
5990
+ const prop = {
5991
+ description: param.description
5992
+ };
5993
+ if (param.type === "string[]") {
5994
+ prop.type = "array";
5995
+ prop.items = { type: "string" };
5996
+ } else {
5997
+ prop.type = param.type;
5998
+ }
5999
+ properties[param.name] = prop;
6000
+ if (param.required) {
6001
+ required.push(param.name);
6002
+ }
6003
+ }
6004
+ return {
6005
+ name: `blockrun_${service.id}`,
6006
+ description: [
6007
+ service.description,
6008
+ "",
6009
+ `Partner: ${service.partner}`,
6010
+ `Pricing: ${service.pricing.perUnit} per ${service.pricing.unit} (min: ${service.pricing.minimum}, max: ${service.pricing.maximum})`
6011
+ ].join("\n"),
6012
+ parameters: {
6013
+ type: "object",
6014
+ properties,
6015
+ required
6016
+ },
6017
+ execute: async (_toolCallId, params) => {
6018
+ const url = `${proxyBaseUrl}/v1${service.proxyPath}`;
6019
+ const response = await fetch(url, {
6020
+ method: service.method,
6021
+ headers: { "Content-Type": "application/json" },
6022
+ body: JSON.stringify(params)
6023
+ });
6024
+ if (!response.ok) {
6025
+ const errText = await response.text().catch(() => "");
6026
+ throw new Error(
6027
+ `Partner API error (${response.status}): ${errText || response.statusText}`
6028
+ );
6029
+ }
6030
+ const data = await response.json();
6031
+ return {
6032
+ content: [
6033
+ {
6034
+ type: "text",
6035
+ text: JSON.stringify(data, null, 2)
6036
+ }
6037
+ ],
6038
+ details: data
6039
+ };
6040
+ }
6041
+ };
6042
+ }
6043
+ function buildPartnerTools(proxyBaseUrl) {
6044
+ return PARTNER_SERVICES.map((service) => buildTool(service, proxyBaseUrl));
6045
+ }
6046
+
6084
6047
  // src/retry.ts
6085
6048
  var DEFAULT_RETRY_CONFIG = {
6086
6049
  maxRetries: 2,
@@ -6138,7 +6101,6 @@ function isRetryable(errorOrResponse, config) {
6138
6101
  }
6139
6102
 
6140
6103
  // src/index.ts
6141
- init_partners();
6142
6104
  async function waitForProxyHealth(port, timeoutMs = 3e3) {
6143
6105
  const start = Date.now();
6144
6106
  while (Date.now() - start < timeoutMs) {
@@ -6561,7 +6523,7 @@ var plugin = {
6561
6523
  name: "ClawRouter",
6562
6524
  description: "Smart LLM router \u2014 30+ models, x402 micropayments, 78% cost savings",
6563
6525
  version: VERSION,
6564
- async register(api) {
6526
+ register(api) {
6565
6527
  const isDisabled = process["env"].CLAWROUTER_DISABLED === "true" || process["env"].CLAWROUTER_DISABLED === "1";
6566
6528
  if (isDisabled) {
6567
6529
  api.logger.info("ClawRouter disabled (CLAWROUTER_DISABLED=true). Using default routing.");
@@ -6590,14 +6552,15 @@ var plugin = {
6590
6552
  };
6591
6553
  api.logger.info("BlockRun provider registered (30+ models via x402)");
6592
6554
  try {
6593
- const { buildPartnerTools: buildPartnerTools2, PARTNER_SERVICES: PARTNER_SERVICES2 } = await Promise.resolve().then(() => (init_partners(), partners_exports));
6594
6555
  const proxyBaseUrl = `http://127.0.0.1:${runtimePort}`;
6595
- const partnerTools = buildPartnerTools2(proxyBaseUrl);
6556
+ const partnerTools = buildPartnerTools(proxyBaseUrl);
6596
6557
  for (const tool of partnerTools) {
6597
6558
  api.registerTool(tool);
6598
6559
  }
6599
6560
  if (partnerTools.length > 0) {
6600
- api.logger.info(`Registered ${partnerTools.length} partner tool(s): ${partnerTools.map((t) => t.name).join(", ")}`);
6561
+ api.logger.info(
6562
+ `Registered ${partnerTools.length} partner tool(s): ${partnerTools.map((t) => t.name).join(", ")}`
6563
+ );
6601
6564
  }
6602
6565
  api.registerCommand({
6603
6566
  name: "partners",
@@ -6605,19 +6568,20 @@ var plugin = {
6605
6568
  acceptsArgs: false,
6606
6569
  requireAuth: false,
6607
6570
  handler: async () => {
6608
- if (PARTNER_SERVICES2.length === 0) {
6571
+ if (PARTNER_SERVICES.length === 0) {
6609
6572
  return { text: "No partner APIs available." };
6610
6573
  }
6611
- const lines = [
6612
- "**Partner APIs** (paid via your ClawRouter wallet)",
6613
- ""
6614
- ];
6615
- for (const svc of PARTNER_SERVICES2) {
6574
+ const lines = ["**Partner APIs** (paid via your ClawRouter wallet)", ""];
6575
+ for (const svc of PARTNER_SERVICES) {
6616
6576
  lines.push(`**${svc.name}** (${svc.partner})`);
6617
6577
  lines.push(` ${svc.description}`);
6618
6578
  lines.push(` Tool: \`${`blockrun_${svc.id}`}\``);
6619
- lines.push(` Pricing: ${svc.pricing.perUnit} per ${svc.pricing.unit} (min ${svc.pricing.minimum}, max ${svc.pricing.maximum})`);
6620
- lines.push(` **How to use:** Ask "Look up Twitter user @elonmusk" or "Get info on these X accounts: @naval, @balajis"`);
6579
+ lines.push(
6580
+ ` Pricing: ${svc.pricing.perUnit} per ${svc.pricing.unit} (min ${svc.pricing.minimum}, max ${svc.pricing.maximum})`
6581
+ );
6582
+ lines.push(
6583
+ ` **How to use:** Ask "Look up Twitter user @elonmusk" or "Get info on these X accounts: @naval, @balajis"`
6584
+ );
6621
6585
  lines.push("");
6622
6586
  }
6623
6587
  return { text: lines.join("\n") };