@blockrun/clawrouter 0.10.4 → 0.10.6

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,3 +1,126 @@
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: "Look up Twitter/X user profiles by username. Returns follower counts, verification status, bio, and more. Accepts up to 100 usernames per request.",
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
+ inputSchema: {
78
+ type: "object",
79
+ properties,
80
+ required
81
+ },
82
+ execute: async (args) => {
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(args)
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
+ return response.json();
96
+ }
97
+ };
98
+ }
99
+ function buildPartnerTools(proxyBaseUrl) {
100
+ return PARTNER_SERVICES.map((service) => buildTool(service, proxyBaseUrl));
101
+ }
102
+ var init_tools = __esm({
103
+ "src/partners/tools.ts"() {
104
+ "use strict";
105
+ init_registry();
106
+ }
107
+ });
108
+
109
+ // src/partners/index.ts
110
+ var partners_exports = {};
111
+ __export(partners_exports, {
112
+ PARTNER_SERVICES: () => PARTNER_SERVICES,
113
+ buildPartnerTools: () => buildPartnerTools,
114
+ getPartnerService: () => getPartnerService
115
+ });
116
+ var init_partners = __esm({
117
+ "src/partners/index.ts"() {
118
+ "use strict";
119
+ init_registry();
120
+ init_tools();
121
+ }
122
+ });
123
+
1
124
  // src/models.ts
2
125
  var MODEL_ALIASES = {
3
126
  // Claude - use newest versions (4.6)
@@ -1170,7 +1293,7 @@ var DEFAULT_ROUTING_CONFIG = {
1170
1293
  },
1171
1294
  scoring: {
1172
1295
  tokenCountThresholds: { simple: 50, complex: 500 },
1173
- // Multilingual keywords: English + Chinese (中文) + Japanese (日本語) + Russian (Русский) + German (Deutsch)
1296
+ // Multilingual keywords: EN + ZH + JA + RU + DE + ES + PT + KO + AR
1174
1297
  codeKeywords: [
1175
1298
  // English
1176
1299
  "function",
@@ -1224,7 +1347,51 @@ var DEFAULT_ROUTING_CONFIG = {
1224
1347
  "erwarten",
1225
1348
  "konstante",
1226
1349
  "variable",
1227
- "zur\xFCckgeben"
1350
+ "zur\xFCckgeben",
1351
+ // Spanish
1352
+ "funci\xF3n",
1353
+ "clase",
1354
+ "importar",
1355
+ "definir",
1356
+ "consulta",
1357
+ "as\xEDncrono",
1358
+ "esperar",
1359
+ "constante",
1360
+ "variable",
1361
+ "retornar",
1362
+ // Portuguese
1363
+ "fun\xE7\xE3o",
1364
+ "classe",
1365
+ "importar",
1366
+ "definir",
1367
+ "consulta",
1368
+ "ass\xEDncrono",
1369
+ "aguardar",
1370
+ "constante",
1371
+ "vari\xE1vel",
1372
+ "retornar",
1373
+ // Korean
1374
+ "\uD568\uC218",
1375
+ "\uD074\uB798\uC2A4",
1376
+ "\uAC00\uC838\uC624\uAE30",
1377
+ "\uC815\uC758",
1378
+ "\uCFFC\uB9AC",
1379
+ "\uBE44\uB3D9\uAE30",
1380
+ "\uB300\uAE30",
1381
+ "\uC0C1\uC218",
1382
+ "\uBCC0\uC218",
1383
+ "\uBC18\uD658",
1384
+ // Arabic
1385
+ "\u062F\u0627\u0644\u0629",
1386
+ "\u0641\u0626\u0629",
1387
+ "\u0627\u0633\u062A\u064A\u0631\u0627\u062F",
1388
+ "\u062A\u0639\u0631\u064A\u0641",
1389
+ "\u0627\u0633\u062A\u0639\u0644\u0627\u0645",
1390
+ "\u063A\u064A\u0631 \u0645\u062A\u0632\u0627\u0645\u0646",
1391
+ "\u0627\u0646\u062A\u0638\u0627\u0631",
1392
+ "\u062B\u0627\u0628\u062A",
1393
+ "\u0645\u062A\u063A\u064A\u0631",
1394
+ "\u0625\u0631\u062C\u0627\u0639"
1228
1395
  ],
1229
1396
  reasoningKeywords: [
1230
1397
  // English
@@ -1275,7 +1442,46 @@ var DEFAULT_ROUTING_CONFIG = {
1275
1442
  "gedankenkette",
1276
1443
  "formal",
1277
1444
  "mathematisch",
1278
- "logisch"
1445
+ "logisch",
1446
+ // Spanish
1447
+ "demostrar",
1448
+ "teorema",
1449
+ "derivar",
1450
+ "paso a paso",
1451
+ "cadena de pensamiento",
1452
+ "formalmente",
1453
+ "matem\xE1tico",
1454
+ "prueba",
1455
+ "l\xF3gicamente",
1456
+ // Portuguese
1457
+ "provar",
1458
+ "teorema",
1459
+ "derivar",
1460
+ "passo a passo",
1461
+ "cadeia de pensamento",
1462
+ "formalmente",
1463
+ "matem\xE1tico",
1464
+ "prova",
1465
+ "logicamente",
1466
+ // Korean
1467
+ "\uC99D\uBA85",
1468
+ "\uC815\uB9AC",
1469
+ "\uB3C4\uCD9C",
1470
+ "\uB2E8\uACC4\uBCC4",
1471
+ "\uC0AC\uACE0\uC758 \uC5F0\uC1C4",
1472
+ "\uD615\uC2DD\uC801",
1473
+ "\uC218\uD559\uC801",
1474
+ "\uB17C\uB9AC\uC801",
1475
+ // Arabic
1476
+ "\u0625\u062B\u0628\u0627\u062A",
1477
+ "\u0646\u0638\u0631\u064A\u0629",
1478
+ "\u0627\u0634\u062A\u0642\u0627\u0642",
1479
+ "\u062E\u0637\u0648\u0629 \u0628\u062E\u0637\u0648\u0629",
1480
+ "\u0633\u0644\u0633\u0644\u0629 \u0627\u0644\u062A\u0641\u0643\u064A\u0631",
1481
+ "\u0631\u0633\u0645\u064A\u0627\u064B",
1482
+ "\u0631\u064A\u0627\u0636\u064A",
1483
+ "\u0628\u0631\u0647\u0627\u0646",
1484
+ "\u0645\u0646\u0637\u0642\u064A\u0627\u064B"
1279
1485
  ],
1280
1486
  simpleKeywords: [
1281
1487
  // English
@@ -1328,7 +1534,45 @@ var DEFAULT_ROUTING_CONFIG = {
1328
1534
  "wie alt",
1329
1535
  "wer ist",
1330
1536
  "wann",
1331
- "erkl\xE4re"
1537
+ "erkl\xE4re",
1538
+ // Spanish
1539
+ "qu\xE9 es",
1540
+ "definir",
1541
+ "traducir",
1542
+ "hola",
1543
+ "s\xED o no",
1544
+ "capital de",
1545
+ "cu\xE1ntos a\xF1os",
1546
+ "qui\xE9n es",
1547
+ "cu\xE1ndo",
1548
+ // Portuguese
1549
+ "o que \xE9",
1550
+ "definir",
1551
+ "traduzir",
1552
+ "ol\xE1",
1553
+ "sim ou n\xE3o",
1554
+ "capital de",
1555
+ "quantos anos",
1556
+ "quem \xE9",
1557
+ "quando",
1558
+ // Korean
1559
+ "\uBB34\uC5C7",
1560
+ "\uC815\uC758",
1561
+ "\uBC88\uC5ED",
1562
+ "\uC548\uB155\uD558\uC138\uC694",
1563
+ "\uC608 \uB610\uB294 \uC544\uB2C8\uC624",
1564
+ "\uC218\uB3C4",
1565
+ "\uB204\uAD6C",
1566
+ "\uC5B8\uC81C",
1567
+ // Arabic
1568
+ "\u0645\u0627 \u0647\u0648",
1569
+ "\u062A\u0639\u0631\u064A\u0641",
1570
+ "\u062A\u0631\u062C\u0645",
1571
+ "\u0645\u0631\u062D\u0628\u0627",
1572
+ "\u0646\u0639\u0645 \u0623\u0648 \u0644\u0627",
1573
+ "\u0639\u0627\u0635\u0645\u0629",
1574
+ "\u0645\u0646 \u0647\u0648",
1575
+ "\u0645\u062A\u0649"
1332
1576
  ],
1333
1577
  technicalKeywords: [
1334
1578
  // English
@@ -1373,7 +1617,39 @@ var DEFAULT_ROUTING_CONFIG = {
1373
1617
  "kubernetes",
1374
1618
  "mikroservice",
1375
1619
  "datenbank",
1376
- "infrastruktur"
1620
+ "infrastruktur",
1621
+ // Spanish
1622
+ "algoritmo",
1623
+ "optimizar",
1624
+ "arquitectura",
1625
+ "distribuido",
1626
+ "microservicio",
1627
+ "base de datos",
1628
+ "infraestructura",
1629
+ // Portuguese
1630
+ "algoritmo",
1631
+ "otimizar",
1632
+ "arquitetura",
1633
+ "distribu\xEDdo",
1634
+ "microsservi\xE7o",
1635
+ "banco de dados",
1636
+ "infraestrutura",
1637
+ // Korean
1638
+ "\uC54C\uACE0\uB9AC\uC998",
1639
+ "\uCD5C\uC801\uD654",
1640
+ "\uC544\uD0A4\uD14D\uCC98",
1641
+ "\uBD84\uC0B0",
1642
+ "\uB9C8\uC774\uD06C\uB85C\uC11C\uBE44\uC2A4",
1643
+ "\uB370\uC774\uD130\uBCA0\uC774\uC2A4",
1644
+ "\uC778\uD504\uB77C",
1645
+ // Arabic
1646
+ "\u062E\u0648\u0627\u0631\u0632\u0645\u064A\u0629",
1647
+ "\u062A\u062D\u0633\u064A\u0646",
1648
+ "\u0628\u0646\u064A\u0629",
1649
+ "\u0645\u0648\u0632\u0639",
1650
+ "\u062E\u062F\u0645\u0629 \u0645\u0635\u063A\u0631\u0629",
1651
+ "\u0642\u0627\u0639\u062F\u0629 \u0628\u064A\u0627\u0646\u0627\u062A",
1652
+ "\u0628\u0646\u064A\u0629 \u062A\u062D\u062A\u064A\u0629"
1377
1653
  ],
1378
1654
  creativeKeywords: [
1379
1655
  // English
@@ -1418,7 +1694,38 @@ var DEFAULT_ROUTING_CONFIG = {
1418
1694
  "kreativ",
1419
1695
  "vorstellen",
1420
1696
  "schreibe",
1421
- "erz\xE4hlung"
1697
+ "erz\xE4hlung",
1698
+ // Spanish
1699
+ "historia",
1700
+ "poema",
1701
+ "componer",
1702
+ "lluvia de ideas",
1703
+ "creativo",
1704
+ "imaginar",
1705
+ "escribe",
1706
+ // Portuguese
1707
+ "hist\xF3ria",
1708
+ "poema",
1709
+ "compor",
1710
+ "criativo",
1711
+ "imaginar",
1712
+ "escreva",
1713
+ // Korean
1714
+ "\uC774\uC57C\uAE30",
1715
+ "\uC2DC",
1716
+ "\uC791\uACE1",
1717
+ "\uBE0C\uB808\uC778\uC2A4\uD1A0\uBC0D",
1718
+ "\uCC3D\uC758\uC801",
1719
+ "\uC0C1\uC0C1",
1720
+ "\uC791\uC131",
1721
+ // Arabic
1722
+ "\u0642\u0635\u0629",
1723
+ "\u0642\u0635\u064A\u062F\u0629",
1724
+ "\u062A\u0623\u0644\u064A\u0641",
1725
+ "\u0639\u0635\u0641 \u0630\u0647\u0646\u064A",
1726
+ "\u0625\u0628\u062F\u0627\u0639\u064A",
1727
+ "\u062A\u062E\u064A\u0644",
1728
+ "\u0627\u0643\u062A\u0628"
1422
1729
  ],
1423
1730
  // New dimension keyword lists (multilingual)
1424
1731
  imperativeVerbs: [
@@ -1479,7 +1786,42 @@ var DEFAULT_ROUTING_CONFIG = {
1479
1786
  "generieren",
1480
1787
  "bereitstellen",
1481
1788
  "konfigurieren",
1482
- "einrichten"
1789
+ "einrichten",
1790
+ // Spanish
1791
+ "construir",
1792
+ "crear",
1793
+ "implementar",
1794
+ "dise\xF1ar",
1795
+ "desarrollar",
1796
+ "generar",
1797
+ "desplegar",
1798
+ "configurar",
1799
+ // Portuguese
1800
+ "construir",
1801
+ "criar",
1802
+ "implementar",
1803
+ "projetar",
1804
+ "desenvolver",
1805
+ "gerar",
1806
+ "implantar",
1807
+ "configurar",
1808
+ // Korean
1809
+ "\uAD6C\uCD95",
1810
+ "\uC0DD\uC131",
1811
+ "\uAD6C\uD604",
1812
+ "\uC124\uACC4",
1813
+ "\uAC1C\uBC1C",
1814
+ "\uBC30\uD3EC",
1815
+ "\uC124\uC815",
1816
+ // Arabic
1817
+ "\u0628\u0646\u0627\u0621",
1818
+ "\u0625\u0646\u0634\u0627\u0621",
1819
+ "\u062A\u0646\u0641\u064A\u0630",
1820
+ "\u062A\u0635\u0645\u064A\u0645",
1821
+ "\u062A\u0637\u0648\u064A\u0631",
1822
+ "\u062A\u0648\u0644\u064A\u062F",
1823
+ "\u0646\u0634\u0631",
1824
+ "\u0625\u0639\u062F\u0627\u062F"
1483
1825
  ],
1484
1826
  constraintIndicators: [
1485
1827
  // English
@@ -1525,7 +1867,41 @@ var DEFAULT_ROUTING_CONFIG = {
1525
1867
  "maximal",
1526
1868
  "minimal",
1527
1869
  "grenze",
1528
- "budget"
1870
+ "budget",
1871
+ // Spanish
1872
+ "como m\xE1ximo",
1873
+ "al menos",
1874
+ "dentro de",
1875
+ "no m\xE1s de",
1876
+ "m\xE1ximo",
1877
+ "m\xEDnimo",
1878
+ "l\xEDmite",
1879
+ "presupuesto",
1880
+ // Portuguese
1881
+ "no m\xE1ximo",
1882
+ "pelo menos",
1883
+ "dentro de",
1884
+ "n\xE3o mais que",
1885
+ "m\xE1ximo",
1886
+ "m\xEDnimo",
1887
+ "limite",
1888
+ "or\xE7amento",
1889
+ // Korean
1890
+ "\uC774\uD558",
1891
+ "\uC774\uC0C1",
1892
+ "\uCD5C\uB300",
1893
+ "\uCD5C\uC18C",
1894
+ "\uC81C\uD55C",
1895
+ "\uC608\uC0B0",
1896
+ // Arabic
1897
+ "\u0639\u0644\u0649 \u0627\u0644\u0623\u0643\u062B\u0631",
1898
+ "\u0639\u0644\u0649 \u0627\u0644\u0623\u0642\u0644",
1899
+ "\u0636\u0645\u0646",
1900
+ "\u0644\u0627 \u064A\u0632\u064A\u062F \u0639\u0646",
1901
+ "\u0623\u0642\u0635\u0649",
1902
+ "\u0623\u062F\u0646\u0649",
1903
+ "\u062D\u062F",
1904
+ "\u0645\u064A\u0632\u0627\u0646\u064A\u0629"
1529
1905
  ],
1530
1906
  outputFormatKeywords: [
1531
1907
  // English
@@ -1553,7 +1929,23 @@ var DEFAULT_ROUTING_CONFIG = {
1553
1929
  // German
1554
1930
  "tabelle",
1555
1931
  "formatieren als",
1556
- "strukturiert"
1932
+ "strukturiert",
1933
+ // Spanish
1934
+ "tabla",
1935
+ "formatear como",
1936
+ "estructurado",
1937
+ // Portuguese
1938
+ "tabela",
1939
+ "formatar como",
1940
+ "estruturado",
1941
+ // Korean
1942
+ "\uD14C\uC774\uBE14",
1943
+ "\uD615\uC2DD",
1944
+ "\uAD6C\uC870\uD654",
1945
+ // Arabic
1946
+ "\u062C\u062F\u0648\u0644",
1947
+ "\u062A\u0646\u0633\u064A\u0642",
1948
+ "\u0645\u0646\u0638\u0645"
1557
1949
  ],
1558
1950
  referenceKeywords: [
1559
1951
  // English
@@ -1598,7 +1990,39 @@ var DEFAULT_ROUTING_CONFIG = {
1598
1990
  "dokumentation",
1599
1991
  "der code",
1600
1992
  "fr\xFCher",
1601
- "anhang"
1993
+ "anhang",
1994
+ // Spanish
1995
+ "arriba",
1996
+ "abajo",
1997
+ "anterior",
1998
+ "siguiente",
1999
+ "documentaci\xF3n",
2000
+ "el c\xF3digo",
2001
+ "adjunto",
2002
+ // Portuguese
2003
+ "acima",
2004
+ "abaixo",
2005
+ "anterior",
2006
+ "seguinte",
2007
+ "documenta\xE7\xE3o",
2008
+ "o c\xF3digo",
2009
+ "anexo",
2010
+ // Korean
2011
+ "\uC704",
2012
+ "\uC544\uB798",
2013
+ "\uC774\uC804",
2014
+ "\uB2E4\uC74C",
2015
+ "\uBB38\uC11C",
2016
+ "\uCF54\uB4DC",
2017
+ "\uCCA8\uBD80",
2018
+ // Arabic
2019
+ "\u0623\u0639\u0644\u0627\u0647",
2020
+ "\u0623\u062F\u0646\u0627\u0647",
2021
+ "\u0627\u0644\u0633\u0627\u0628\u0642",
2022
+ "\u0627\u0644\u062A\u0627\u0644\u064A",
2023
+ "\u0627\u0644\u0648\u062B\u0627\u0626\u0642",
2024
+ "\u0627\u0644\u0643\u0648\u062F",
2025
+ "\u0645\u0631\u0641\u0642"
1602
2026
  ],
1603
2027
  negationKeywords: [
1604
2028
  // English
@@ -1640,7 +2064,34 @@ var DEFAULT_ROUTING_CONFIG = {
1640
2064
  "ohne",
1641
2065
  "au\xDFer",
1642
2066
  "ausschlie\xDFen",
1643
- "nicht mehr"
2067
+ "nicht mehr",
2068
+ // Spanish
2069
+ "no hagas",
2070
+ "evitar",
2071
+ "nunca",
2072
+ "sin",
2073
+ "excepto",
2074
+ "excluir",
2075
+ // Portuguese
2076
+ "n\xE3o fa\xE7a",
2077
+ "evitar",
2078
+ "nunca",
2079
+ "sem",
2080
+ "exceto",
2081
+ "excluir",
2082
+ // Korean
2083
+ "\uD558\uC9C0 \uB9C8",
2084
+ "\uD53C\uD558\uB2E4",
2085
+ "\uC808\uB300",
2086
+ "\uC5C6\uC774",
2087
+ "\uC81C\uC678",
2088
+ // Arabic
2089
+ "\u0644\u0627 \u062A\u0641\u0639\u0644",
2090
+ "\u062A\u062C\u0646\u0628",
2091
+ "\u0623\u0628\u062F\u0627\u064B",
2092
+ "\u0628\u062F\u0648\u0646",
2093
+ "\u0628\u0627\u0633\u062A\u062B\u0646\u0627\u0621",
2094
+ "\u0627\u0633\u062A\u0628\u0639\u0627\u062F"
1644
2095
  ],
1645
2096
  domainSpecificKeywords: [
1646
2097
  // English
@@ -1687,7 +2138,33 @@ var DEFAULT_ROUTING_CONFIG = {
1687
2138
  "topologisch",
1688
2139
  "homomorph",
1689
2140
  "zero-knowledge",
1690
- "gitterbasiert"
2141
+ "gitterbasiert",
2142
+ // Spanish
2143
+ "cu\xE1ntico",
2144
+ "fot\xF3nica",
2145
+ "gen\xF3mica",
2146
+ "prote\xF3mica",
2147
+ "topol\xF3gico",
2148
+ "homom\xF3rfico",
2149
+ // Portuguese
2150
+ "qu\xE2ntico",
2151
+ "fot\xF4nica",
2152
+ "gen\xF4mica",
2153
+ "prote\xF4mica",
2154
+ "topol\xF3gico",
2155
+ "homom\xF3rfico",
2156
+ // Korean
2157
+ "\uC591\uC790",
2158
+ "\uD3EC\uD1A0\uB2C9\uC2A4",
2159
+ "\uC720\uC804\uCCB4\uD559",
2160
+ "\uC704\uC0C1",
2161
+ "\uB3D9\uD615",
2162
+ // Arabic
2163
+ "\u0643\u0645\u064A",
2164
+ "\u0636\u0648\u0626\u064A\u0627\u062A",
2165
+ "\u062C\u064A\u0646\u0648\u0645\u064A\u0627\u062A",
2166
+ "\u0637\u0648\u0628\u0648\u0644\u0648\u062C\u064A",
2167
+ "\u062A\u0645\u0627\u062B\u0644\u064A"
1691
2168
  ],
1692
2169
  // Agentic task keywords - file ops, execution, multi-step, iterative work
1693
2170
  // Pruned: removed overly common words like "then", "first", "run", "test", "build"
@@ -1743,7 +2220,58 @@ var DEFAULT_ROUTING_CONFIG = {
1743
2220
  "\u8C03\u8BD5",
1744
2221
  "\u76F4\u5230",
1745
2222
  "\u786E\u8BA4",
1746
- "\u9A8C\u8BC1"
2223
+ "\u9A8C\u8BC1",
2224
+ // Spanish
2225
+ "leer archivo",
2226
+ "editar",
2227
+ "modificar",
2228
+ "actualizar",
2229
+ "ejecutar",
2230
+ "desplegar",
2231
+ "instalar",
2232
+ "paso 1",
2233
+ "paso 2",
2234
+ "arreglar",
2235
+ "depurar",
2236
+ "verificar",
2237
+ // Portuguese
2238
+ "ler arquivo",
2239
+ "editar",
2240
+ "modificar",
2241
+ "atualizar",
2242
+ "executar",
2243
+ "implantar",
2244
+ "instalar",
2245
+ "passo 1",
2246
+ "passo 2",
2247
+ "corrigir",
2248
+ "depurar",
2249
+ "verificar",
2250
+ // Korean
2251
+ "\uD30C\uC77C \uC77D\uAE30",
2252
+ "\uD3B8\uC9D1",
2253
+ "\uC218\uC815",
2254
+ "\uC5C5\uB370\uC774\uD2B8",
2255
+ "\uC2E4\uD589",
2256
+ "\uBC30\uD3EC",
2257
+ "\uC124\uCE58",
2258
+ "\uB2E8\uACC4 1",
2259
+ "\uB2E8\uACC4 2",
2260
+ "\uB514\uBC84\uADF8",
2261
+ "\uD655\uC778",
2262
+ // Arabic
2263
+ "\u0642\u0631\u0627\u0621\u0629 \u0645\u0644\u0641",
2264
+ "\u062A\u062D\u0631\u064A\u0631",
2265
+ "\u062A\u0639\u062F\u064A\u0644",
2266
+ "\u062A\u062D\u062F\u064A\u062B",
2267
+ "\u062A\u0646\u0641\u064A\u0630",
2268
+ "\u0646\u0634\u0631",
2269
+ "\u062A\u062B\u0628\u064A\u062A",
2270
+ "\u0627\u0644\u062E\u0637\u0648\u0629 1",
2271
+ "\u0627\u0644\u062E\u0637\u0648\u0629 2",
2272
+ "\u0625\u0635\u0644\u0627\u062D",
2273
+ "\u062A\u0635\u062D\u064A\u062D",
2274
+ "\u062A\u062D\u0642\u0642"
1747
2275
  ],
1748
2276
  // Dimension weights (sum to 1.0)
1749
2277
  dimensionWeights: {
@@ -2230,7 +2758,7 @@ function formatStatsAscii(stats) {
2230
2758
  lines.push(`\u2551 Avg Latency: ${stats.avgLatencyMs.toFixed(0)}ms`.padEnd(61) + "\u2551");
2231
2759
  lines.push("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563");
2232
2760
  lines.push("\u2551 Routing by Tier: \u2551");
2233
- const knownTiers = ["SIMPLE", "MEDIUM", "COMPLEX", "REASONING"];
2761
+ const knownTiers = ["SIMPLE", "MEDIUM", "COMPLEX", "REASONING", "DIRECT"];
2234
2762
  const allTiers = Object.keys(stats.byTier);
2235
2763
  const otherTiers = allTiers.filter((t) => !knownTiers.includes(t));
2236
2764
  const tierOrder = [...knownTiers.filter((t) => stats.byTier[t]), ...otherTiers];
@@ -4340,6 +4868,63 @@ function estimateAmount(modelId, bodyLength, maxTokens) {
4340
4868
  const amountMicros = Math.max(100, Math.ceil(costUsd * 1.2 * 1e6));
4341
4869
  return amountMicros.toString();
4342
4870
  }
4871
+ async function proxyPartnerRequest(req, res, apiBase, payFetch) {
4872
+ const startTime = Date.now();
4873
+ const upstreamUrl = `${apiBase}${req.url}`;
4874
+ const bodyChunks = [];
4875
+ for await (const chunk of req) {
4876
+ bodyChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
4877
+ }
4878
+ const body = Buffer.concat(bodyChunks);
4879
+ const headers = {};
4880
+ for (const [key, value] of Object.entries(req.headers)) {
4881
+ if (key === "host" || key === "connection" || key === "transfer-encoding" || key === "content-length")
4882
+ continue;
4883
+ if (typeof value === "string") headers[key] = value;
4884
+ }
4885
+ if (!headers["content-type"]) headers["content-type"] = "application/json";
4886
+ headers["user-agent"] = USER_AGENT;
4887
+ console.log(`[ClawRouter] Partner request: ${req.method} ${req.url}`);
4888
+ const upstream = await payFetch(upstreamUrl, {
4889
+ method: req.method ?? "POST",
4890
+ headers,
4891
+ body: body.length > 0 ? new Uint8Array(body) : void 0
4892
+ });
4893
+ const responseHeaders = {};
4894
+ upstream.headers.forEach((value, key) => {
4895
+ if (key === "transfer-encoding" || key === "connection" || key === "content-encoding") return;
4896
+ responseHeaders[key] = value;
4897
+ });
4898
+ res.writeHead(upstream.status, responseHeaders);
4899
+ if (upstream.body) {
4900
+ const reader = upstream.body.getReader();
4901
+ try {
4902
+ while (true) {
4903
+ const { done, value } = await reader.read();
4904
+ if (done) break;
4905
+ safeWrite(res, Buffer.from(value));
4906
+ }
4907
+ } finally {
4908
+ reader.releaseLock();
4909
+ }
4910
+ }
4911
+ res.end();
4912
+ const latencyMs = Date.now() - startTime;
4913
+ console.log(`[ClawRouter] Partner response: ${upstream.status} (${latencyMs}ms)`);
4914
+ logUsage({
4915
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
4916
+ model: "partner",
4917
+ tier: "PARTNER",
4918
+ cost: 0,
4919
+ // Actual cost handled by x402 settlement
4920
+ baselineCost: 0,
4921
+ savings: 0,
4922
+ latencyMs,
4923
+ partnerId: (req.url?.split("?")[0] ?? "").replace(/^\/v1\//, "").replace(/\//g, "_") || "unknown",
4924
+ service: "partner"
4925
+ }).catch(() => {
4926
+ });
4927
+ }
4343
4928
  async function startProxy(options) {
4344
4929
  const apiBase = options.apiBase ?? BLOCKRUN_API;
4345
4930
  const listenPort = options.port ?? getProxyPort();
@@ -4450,6 +5035,23 @@ async function startProxy(options) {
4450
5035
  res.end(JSON.stringify({ object: "list", data: models }));
4451
5036
  return;
4452
5037
  }
5038
+ if (req.url?.match(/^\/v1\/(?:x|partner)\//)) {
5039
+ try {
5040
+ await proxyPartnerRequest(req, res, apiBase, payFetch);
5041
+ } catch (err) {
5042
+ const error = err instanceof Error ? err : new Error(String(err));
5043
+ options.onError?.(error);
5044
+ if (!res.headersSent) {
5045
+ res.writeHead(502, { "Content-Type": "application/json" });
5046
+ res.end(
5047
+ JSON.stringify({
5048
+ error: { message: `Partner proxy error: ${error.message}`, type: "partner_error" }
5049
+ })
5050
+ );
5051
+ }
5052
+ }
5053
+ return;
5054
+ }
4453
5055
  if (!req.url?.startsWith("/v1")) {
4454
5056
  res.writeHead(404, { "Content-Type": "application/json" });
4455
5057
  res.end(JSON.stringify({ error: "Not found" }));
@@ -5312,10 +5914,11 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
5312
5914
  }
5313
5915
  throw err;
5314
5916
  }
5315
- if (routingDecision) {
5917
+ const logModel = routingDecision?.model ?? modelId;
5918
+ if (logModel) {
5316
5919
  const estimatedInputTokens = Math.ceil(body.length / 4);
5317
5920
  const accurateCosts = calculateModelCost(
5318
- routingDecision.model,
5921
+ logModel,
5319
5922
  routerOpts.modelPricing,
5320
5923
  estimatedInputTokens,
5321
5924
  maxTokens,
@@ -5325,8 +5928,8 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
5325
5928
  const baselineWithBuffer = accurateCosts.baselineCost * 1.2;
5326
5929
  const entry = {
5327
5930
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
5328
- model: routingDecision.model,
5329
- tier: routingDecision.tier,
5931
+ model: logModel,
5932
+ tier: routingDecision?.tier ?? "DIRECT",
5330
5933
  cost: costWithBuffer,
5331
5934
  baselineCost: baselineWithBuffer,
5332
5935
  savings: accurateCosts.savings,
@@ -5464,6 +6067,7 @@ function isRetryable(errorOrResponse, config) {
5464
6067
  }
5465
6068
 
5466
6069
  // src/index.ts
6070
+ init_partners();
5467
6071
  async function waitForProxyHealth(port, timeoutMs = 3e3) {
5468
6072
  const start = Date.now();
5469
6073
  while (Date.now() - start < timeoutMs) {
@@ -5909,6 +6513,44 @@ var plugin = {
5909
6513
  models: OPENCLAW_MODELS
5910
6514
  };
5911
6515
  api.logger.info("BlockRun provider registered (30+ models via x402)");
6516
+ try {
6517
+ const { buildPartnerTools: buildPartnerTools2, PARTNER_SERVICES: PARTNER_SERVICES2 } = await Promise.resolve().then(() => (init_partners(), partners_exports));
6518
+ const proxyBaseUrl = `http://127.0.0.1:${runtimePort}`;
6519
+ const partnerTools = buildPartnerTools2(proxyBaseUrl);
6520
+ for (const tool of partnerTools) {
6521
+ api.registerTool(tool);
6522
+ }
6523
+ if (partnerTools.length > 0) {
6524
+ api.logger.info(`Registered ${partnerTools.length} partner tool(s): ${partnerTools.map((t) => t.name).join(", ")}`);
6525
+ }
6526
+ api.registerCommand({
6527
+ name: "partners",
6528
+ description: "List available partner APIs and pricing",
6529
+ acceptsArgs: false,
6530
+ requireAuth: false,
6531
+ handler: async () => {
6532
+ if (PARTNER_SERVICES2.length === 0) {
6533
+ return { text: "No partner APIs available." };
6534
+ }
6535
+ const lines = [
6536
+ "**Partner APIs** (paid via your ClawRouter wallet)",
6537
+ ""
6538
+ ];
6539
+ for (const svc of PARTNER_SERVICES2) {
6540
+ lines.push(`**${svc.name}** (${svc.partner})`);
6541
+ lines.push(` ${svc.description}`);
6542
+ lines.push(` Tool: \`${`blockrun_${svc.id}`}\``);
6543
+ lines.push(` Pricing: ${svc.pricing.perUnit} per ${svc.pricing.unit} (min ${svc.pricing.minimum}, max ${svc.pricing.maximum})`);
6544
+ lines.push("");
6545
+ }
6546
+ return { text: lines.join("\n") };
6547
+ }
6548
+ });
6549
+ } catch (err) {
6550
+ api.logger.warn(
6551
+ `Failed to register partner tools: ${err instanceof Error ? err.message : String(err)}`
6552
+ );
6553
+ }
5912
6554
  createWalletCommand().then((walletCommand) => {
5913
6555
  api.registerCommand(walletCommand);
5914
6556
  }).catch((err) => {
@@ -5983,12 +6625,14 @@ export {
5983
6625
  InsufficientFundsError,
5984
6626
  MODEL_ALIASES,
5985
6627
  OPENCLAW_MODELS,
6628
+ PARTNER_SERVICES,
5986
6629
  PaymentCache,
5987
6630
  RequestDeduplicator,
5988
6631
  ResponseCache,
5989
6632
  RpcError,
5990
6633
  SessionStore,
5991
6634
  blockrunProvider,
6635
+ buildPartnerTools,
5992
6636
  buildProviderModels,
5993
6637
  calculateModelCost,
5994
6638
  createPaymentFetch,
@@ -5999,6 +6643,7 @@ export {
5999
6643
  getFallbackChain,
6000
6644
  getFallbackChainFiltered,
6001
6645
  getModelContextWindow,
6646
+ getPartnerService,
6002
6647
  getProxyPort,
6003
6648
  getSessionId,
6004
6649
  getStats,