@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/README.md +2 -2
- package/dist/cli.js +23 -21
- package/dist/cli.js.map +1 -1
- package/dist/index.js +129 -165
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
428
|
-
name: "Gemini 3.1 Pro
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
988
|
+
scoreMultiStep(userText),
|
|
1123
989
|
scoreQuestionComplexity(prompt),
|
|
1124
990
|
// 6 new dimensions
|
|
1125
991
|
scoreKeywordMatch(
|
|
1126
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
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(
|
|
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 (
|
|
6571
|
+
if (PARTNER_SERVICES.length === 0) {
|
|
6609
6572
|
return { text: "No partner APIs available." };
|
|
6610
6573
|
}
|
|
6611
|
-
const lines = [
|
|
6612
|
-
|
|
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(
|
|
6620
|
-
|
|
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") };
|