@blockrun/clawrouter 0.12.94 → 0.12.96

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.
Files changed (282) hide show
  1. package/dist/auth.d.ts +82 -0
  2. package/dist/auth.d.ts.map +1 -0
  3. package/dist/auth.js +388 -0
  4. package/dist/auth.js.map +1 -0
  5. package/dist/balance.d.ts +97 -0
  6. package/dist/balance.d.ts.map +1 -0
  7. package/dist/balance.js +157 -0
  8. package/dist/balance.js.map +1 -0
  9. package/dist/cli.d.ts +15 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +256 -54991
  12. package/dist/cli.js.map +1 -1
  13. package/dist/compression/codebook.d.ts +24 -0
  14. package/dist/compression/codebook.d.ts.map +1 -0
  15. package/dist/compression/codebook.js +119 -0
  16. package/dist/compression/codebook.js.map +1 -0
  17. package/dist/compression/index.d.ts +33 -0
  18. package/dist/compression/index.d.ts.map +1 -0
  19. package/dist/compression/index.js +246 -0
  20. package/dist/compression/index.js.map +1 -0
  21. package/dist/compression/layers/deduplication.d.ts +28 -0
  22. package/dist/compression/layers/deduplication.d.ts.map +1 -0
  23. package/dist/compression/layers/deduplication.js +101 -0
  24. package/dist/compression/layers/deduplication.js.map +1 -0
  25. package/dist/compression/layers/dictionary.d.ts +21 -0
  26. package/dist/compression/layers/dictionary.d.ts.map +1 -0
  27. package/dist/compression/layers/dictionary.js +73 -0
  28. package/dist/compression/layers/dictionary.js.map +1 -0
  29. package/dist/compression/layers/dynamic-codebook.d.ts +26 -0
  30. package/dist/compression/layers/dynamic-codebook.d.ts.map +1 -0
  31. package/dist/compression/layers/dynamic-codebook.js +149 -0
  32. package/dist/compression/layers/dynamic-codebook.js.map +1 -0
  33. package/dist/compression/layers/json-compact.d.ts +23 -0
  34. package/dist/compression/layers/json-compact.d.ts.map +1 -0
  35. package/dist/compression/layers/json-compact.js +79 -0
  36. package/dist/compression/layers/json-compact.js.map +1 -0
  37. package/dist/compression/layers/observation.d.ts +21 -0
  38. package/dist/compression/layers/observation.d.ts.map +1 -0
  39. package/dist/compression/layers/observation.js +130 -0
  40. package/dist/compression/layers/observation.js.map +1 -0
  41. package/dist/compression/layers/paths.d.ts +24 -0
  42. package/dist/compression/layers/paths.d.ts.map +1 -0
  43. package/dist/compression/layers/paths.js +110 -0
  44. package/dist/compression/layers/paths.js.map +1 -0
  45. package/dist/compression/layers/whitespace.d.ts +27 -0
  46. package/dist/compression/layers/whitespace.d.ts.map +1 -0
  47. package/dist/compression/layers/whitespace.js +60 -0
  48. package/dist/compression/layers/whitespace.js.map +1 -0
  49. package/dist/compression/types.d.ts +84 -0
  50. package/dist/compression/types.d.ts.map +1 -0
  51. package/dist/compression/types.js +27 -0
  52. package/dist/compression/types.js.map +1 -0
  53. package/dist/config.d.ts +12 -0
  54. package/dist/config.d.ts.map +1 -0
  55. package/dist/config.js +22 -0
  56. package/dist/config.js.map +1 -0
  57. package/dist/dedup.d.ts +34 -0
  58. package/dist/dedup.d.ts.map +1 -0
  59. package/dist/dedup.js +150 -0
  60. package/dist/dedup.js.map +1 -0
  61. package/dist/doctor.d.ts +8 -0
  62. package/dist/doctor.d.ts.map +1 -0
  63. package/dist/doctor.js +375 -0
  64. package/dist/doctor.js.map +1 -0
  65. package/dist/error-classification.test.d.ts +2 -0
  66. package/dist/error-classification.test.d.ts.map +1 -0
  67. package/dist/error-classification.test.js +59 -0
  68. package/dist/error-classification.test.js.map +1 -0
  69. package/dist/errors.d.ts +54 -0
  70. package/dist/errors.d.ts.map +1 -0
  71. package/dist/errors.js +85 -0
  72. package/dist/errors.js.map +1 -0
  73. package/dist/exclude-models.d.ts +28 -0
  74. package/dist/exclude-models.d.ts.map +1 -0
  75. package/dist/exclude-models.integration.test.d.ts +2 -0
  76. package/dist/exclude-models.integration.test.d.ts.map +1 -0
  77. package/dist/exclude-models.integration.test.js +46 -0
  78. package/dist/exclude-models.integration.test.js.map +1 -0
  79. package/dist/exclude-models.js +70 -0
  80. package/dist/exclude-models.js.map +1 -0
  81. package/dist/exclude-models.test.d.ts +5 -0
  82. package/dist/exclude-models.test.d.ts.map +1 -0
  83. package/dist/exclude-models.test.js +95 -0
  84. package/dist/exclude-models.test.js.map +1 -0
  85. package/dist/fs-read.d.ts +11 -0
  86. package/dist/fs-read.d.ts.map +1 -0
  87. package/dist/fs-read.js +47 -0
  88. package/dist/fs-read.js.map +1 -0
  89. package/dist/index.d.ts +34 -1368
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +1071 -56191
  92. package/dist/index.js.map +1 -1
  93. package/dist/journal.d.ts +67 -0
  94. package/dist/journal.d.ts.map +1 -0
  95. package/dist/journal.js +184 -0
  96. package/dist/journal.js.map +1 -0
  97. package/dist/journal.test.d.ts +2 -0
  98. package/dist/journal.test.d.ts.map +1 -0
  99. package/dist/journal.test.js +201 -0
  100. package/dist/journal.test.js.map +1 -0
  101. package/dist/logger.d.ts +33 -0
  102. package/dist/logger.d.ts.map +1 -0
  103. package/dist/logger.js +35 -0
  104. package/dist/logger.js.map +1 -0
  105. package/dist/models.d.ts +107 -0
  106. package/dist/models.d.ts.map +1 -0
  107. package/dist/models.js +941 -0
  108. package/dist/models.js.map +1 -0
  109. package/dist/models.test.d.ts +2 -0
  110. package/dist/models.test.d.ts.map +1 -0
  111. package/dist/models.test.js +38 -0
  112. package/dist/models.test.js.map +1 -0
  113. package/dist/partners/index.d.ts +8 -0
  114. package/dist/partners/index.d.ts.map +1 -0
  115. package/dist/partners/index.js +6 -0
  116. package/dist/partners/index.js.map +1 -0
  117. package/dist/partners/registry.d.ts +51 -0
  118. package/dist/partners/registry.d.ts.map +1 -0
  119. package/dist/partners/registry.js +256 -0
  120. package/dist/partners/registry.js.map +1 -0
  121. package/dist/partners/tools.d.ts +24 -0
  122. package/dist/partners/tools.d.ts.map +1 -0
  123. package/dist/partners/tools.js +97 -0
  124. package/dist/partners/tools.js.map +1 -0
  125. package/dist/payment-preauth.d.ts +17 -0
  126. package/dist/payment-preauth.d.ts.map +1 -0
  127. package/dist/payment-preauth.js +102 -0
  128. package/dist/payment-preauth.js.map +1 -0
  129. package/dist/provider.d.ts +19 -0
  130. package/dist/provider.d.ts.map +1 -0
  131. package/dist/provider.js +45 -0
  132. package/dist/provider.js.map +1 -0
  133. package/dist/proxy.d.ts +210 -0
  134. package/dist/proxy.d.ts.map +1 -0
  135. package/dist/proxy.debrand.test.d.ts +2 -0
  136. package/dist/proxy.debrand.test.d.ts.map +1 -0
  137. package/dist/proxy.debrand.test.js +101 -0
  138. package/dist/proxy.debrand.test.js.map +1 -0
  139. package/dist/proxy.degraded-response.test.d.ts +2 -0
  140. package/dist/proxy.degraded-response.test.d.ts.map +1 -0
  141. package/dist/proxy.degraded-response.test.js +105 -0
  142. package/dist/proxy.degraded-response.test.js.map +1 -0
  143. package/dist/proxy.image-download.test.d.ts +2 -0
  144. package/dist/proxy.image-download.test.d.ts.map +1 -0
  145. package/dist/proxy.image-download.test.js +92 -0
  146. package/dist/proxy.image-download.test.js.map +1 -0
  147. package/dist/proxy.js +3810 -0
  148. package/dist/proxy.js.map +1 -0
  149. package/dist/proxy.models-endpoint.test.d.ts +2 -0
  150. package/dist/proxy.models-endpoint.test.d.ts.map +1 -0
  151. package/dist/proxy.models-endpoint.test.js +19 -0
  152. package/dist/proxy.models-endpoint.test.js.map +1 -0
  153. package/dist/proxy.multiturn-thinking.test.d.ts +2 -0
  154. package/dist/proxy.multiturn-thinking.test.d.ts.map +1 -0
  155. package/dist/proxy.multiturn-thinking.test.js +82 -0
  156. package/dist/proxy.multiturn-thinking.test.js.map +1 -0
  157. package/dist/proxy.payment-chain-reuse.test.d.ts +2 -0
  158. package/dist/proxy.payment-chain-reuse.test.d.ts.map +1 -0
  159. package/dist/proxy.payment-chain-reuse.test.js +30 -0
  160. package/dist/proxy.payment-chain-reuse.test.js.map +1 -0
  161. package/dist/proxy.solana-resilience.test.d.ts +12 -0
  162. package/dist/proxy.solana-resilience.test.d.ts.map +1 -0
  163. package/dist/proxy.solana-resilience.test.js +39 -0
  164. package/dist/proxy.solana-resilience.test.js.map +1 -0
  165. package/dist/report.d.ts +6 -0
  166. package/dist/report.d.ts.map +1 -0
  167. package/dist/report.js +44 -0
  168. package/dist/report.js.map +1 -0
  169. package/dist/response-cache.advanced.test.d.ts +2 -0
  170. package/dist/response-cache.advanced.test.d.ts.map +1 -0
  171. package/dist/response-cache.advanced.test.js +566 -0
  172. package/dist/response-cache.advanced.test.js.map +1 -0
  173. package/dist/response-cache.d.ts +85 -0
  174. package/dist/response-cache.d.ts.map +1 -0
  175. package/dist/response-cache.edge-cases.test.d.ts +2 -0
  176. package/dist/response-cache.edge-cases.test.d.ts.map +1 -0
  177. package/dist/response-cache.edge-cases.test.js +488 -0
  178. package/dist/response-cache.edge-cases.test.js.map +1 -0
  179. package/dist/response-cache.extreme.test.d.ts +2 -0
  180. package/dist/response-cache.extreme.test.d.ts.map +1 -0
  181. package/dist/response-cache.extreme.test.js +561 -0
  182. package/dist/response-cache.extreme.test.js.map +1 -0
  183. package/dist/response-cache.js +240 -0
  184. package/dist/response-cache.js.map +1 -0
  185. package/dist/response-cache.test.d.ts +2 -0
  186. package/dist/response-cache.test.d.ts.map +1 -0
  187. package/dist/response-cache.test.js +242 -0
  188. package/dist/response-cache.test.js.map +1 -0
  189. package/dist/retry.d.ts +42 -0
  190. package/dist/retry.d.ts.map +1 -0
  191. package/dist/retry.js +99 -0
  192. package/dist/retry.js.map +1 -0
  193. package/dist/router/config.d.ts +11 -0
  194. package/dist/router/config.d.ts.map +1 -0
  195. package/dist/router/config.js +1215 -0
  196. package/dist/router/config.js.map +1 -0
  197. package/dist/router/index.d.ts +18 -0
  198. package/dist/router/index.d.ts.map +1 -0
  199. package/dist/router/index.js +19 -0
  200. package/dist/router/index.js.map +1 -0
  201. package/dist/router/llm-classifier.d.ts +29 -0
  202. package/dist/router/llm-classifier.d.ts.map +1 -0
  203. package/dist/router/llm-classifier.js +99 -0
  204. package/dist/router/llm-classifier.js.map +1 -0
  205. package/dist/router/rules.d.ts +12 -0
  206. package/dist/router/rules.d.ts.map +1 -0
  207. package/dist/router/rules.js +202 -0
  208. package/dist/router/rules.js.map +1 -0
  209. package/dist/router/selector.d.ts +58 -0
  210. package/dist/router/selector.d.ts.map +1 -0
  211. package/dist/router/selector.js +165 -0
  212. package/dist/router/selector.js.map +1 -0
  213. package/dist/router/selector.test.d.ts +2 -0
  214. package/dist/router/selector.test.d.ts.map +1 -0
  215. package/dist/router/selector.test.js +67 -0
  216. package/dist/router/selector.test.js.map +1 -0
  217. package/dist/router/strategy.d.ts +19 -0
  218. package/dist/router/strategy.d.ts.map +1 -0
  219. package/dist/router/strategy.js +138 -0
  220. package/dist/router/strategy.js.map +1 -0
  221. package/dist/router/strategy.test.d.ts +2 -0
  222. package/dist/router/strategy.test.d.ts.map +1 -0
  223. package/dist/router/strategy.test.js +131 -0
  224. package/dist/router/strategy.test.js.map +1 -0
  225. package/dist/router/types.d.ts +127 -0
  226. package/dist/router/types.d.ts.map +1 -0
  227. package/dist/router/types.js +11 -0
  228. package/dist/router/types.js.map +1 -0
  229. package/dist/session.d.ts +124 -0
  230. package/dist/session.d.ts.map +1 -0
  231. package/dist/session.js +256 -0
  232. package/dist/session.js.map +1 -0
  233. package/dist/session.test.d.ts +2 -0
  234. package/dist/session.test.d.ts.map +1 -0
  235. package/dist/session.test.js +163 -0
  236. package/dist/session.test.js.map +1 -0
  237. package/dist/solana-balance.d.ts +48 -0
  238. package/dist/solana-balance.d.ts.map +1 -0
  239. package/dist/solana-balance.js +142 -0
  240. package/dist/solana-balance.js.map +1 -0
  241. package/dist/spend-control.d.ts +112 -0
  242. package/dist/spend-control.d.ts.map +1 -0
  243. package/dist/spend-control.js +278 -0
  244. package/dist/spend-control.js.map +1 -0
  245. package/dist/spend-control.test.d.ts +5 -0
  246. package/dist/spend-control.test.d.ts.map +1 -0
  247. package/dist/spend-control.test.js +210 -0
  248. package/dist/spend-control.test.js.map +1 -0
  249. package/dist/stats.d.ts +64 -0
  250. package/dist/stats.d.ts.map +1 -0
  251. package/dist/stats.js +295 -0
  252. package/dist/stats.js.map +1 -0
  253. package/dist/types.d.ts +150 -0
  254. package/dist/types.d.ts.map +1 -0
  255. package/dist/types.js +9 -0
  256. package/dist/types.js.map +1 -0
  257. package/dist/update-hint.test.d.ts +9 -0
  258. package/dist/update-hint.test.d.ts.map +1 -0
  259. package/dist/update-hint.test.js +156 -0
  260. package/dist/update-hint.test.js.map +1 -0
  261. package/dist/updater.d.ts +10 -0
  262. package/dist/updater.d.ts.map +1 -0
  263. package/dist/updater.js +55 -0
  264. package/dist/updater.js.map +1 -0
  265. package/dist/version.d.ts +3 -0
  266. package/dist/version.d.ts.map +1 -0
  267. package/dist/version.js +16 -0
  268. package/dist/version.js.map +1 -0
  269. package/dist/wallet.d.ts +52 -0
  270. package/dist/wallet.d.ts.map +1 -0
  271. package/dist/wallet.js +93 -0
  272. package/dist/wallet.js.map +1 -0
  273. package/dist/wallet.test.d.ts +6 -0
  274. package/dist/wallet.test.d.ts.map +1 -0
  275. package/dist/wallet.test.js +117 -0
  276. package/dist/wallet.test.js.map +1 -0
  277. package/dist/x402-sdk.test.d.ts +6 -0
  278. package/dist/x402-sdk.test.d.ts.map +1 -0
  279. package/dist/x402-sdk.test.js +161 -0
  280. package/dist/x402-sdk.test.js.map +1 -0
  281. package/package.json +2 -2
  282. package/scripts/e2e-multiturn.mjs +4 -1
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Payment Pre-Auth Cache
3
+ *
4
+ * Wraps the @x402/fetch SDK with pre-authorization caching.
5
+ * After the first 402 response, caches payment requirements per endpoint.
6
+ * On subsequent requests, pre-signs payment and attaches it to the first
7
+ * request, skipping the 402 round trip (~200ms savings per request).
8
+ *
9
+ * Falls back to normal 402 flow if pre-signed payment is rejected.
10
+ */
11
+ import { x402HTTPClient } from "@x402/fetch";
12
+ const DEFAULT_TTL_MS = 3_600_000; // 1 hour
13
+ export function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, options) {
14
+ const httpClient = new x402HTTPClient(client);
15
+ const cache = new Map();
16
+ return async (input, init) => {
17
+ const request = new Request(input, init);
18
+ const urlPath = new URL(request.url).pathname;
19
+ // Extract model from request body to create model-specific cache keys.
20
+ // Without this, a cached payment from a paid model (e.g. sonnet) would be
21
+ // incorrectly applied to a free model (nvidia/gpt-oss-120b), causing
22
+ // payment errors even when the server wouldn't charge for the request.
23
+ let requestModel = "";
24
+ if (init?.body) {
25
+ try {
26
+ const bodyStr = init.body instanceof Uint8Array
27
+ ? new TextDecoder().decode(init.body)
28
+ : typeof init.body === "string"
29
+ ? init.body
30
+ : "";
31
+ if (bodyStr) {
32
+ const parsed = JSON.parse(bodyStr);
33
+ requestModel = parsed.model ?? "";
34
+ }
35
+ }
36
+ catch {
37
+ /* not JSON, use empty model */
38
+ }
39
+ }
40
+ const cacheKey = `${urlPath}:${requestModel}`;
41
+ // Try pre-auth if we have cached payment requirements
42
+ // Skip for Solana: payments use per-tx blockhashes that expire ~60-90s,
43
+ // making cached requirements useless and causing double charges.
44
+ const cached = !options?.skipPreAuth ? cache.get(cacheKey) : undefined;
45
+ if (cached && Date.now() - cached.cachedAt < ttlMs) {
46
+ try {
47
+ const payload = await client.createPaymentPayload(cached.paymentRequired);
48
+ const headers = httpClient.encodePaymentSignatureHeader(payload);
49
+ const preAuthRequest = request.clone();
50
+ for (const [key, value] of Object.entries(headers)) {
51
+ preAuthRequest.headers.set(key, value);
52
+ }
53
+ const response = await baseFetch(preAuthRequest);
54
+ if (response.status !== 402) {
55
+ return response; // Pre-auth worked — saved ~200ms
56
+ }
57
+ // Pre-auth rejected (params may have changed) — invalidate and fall through
58
+ cache.delete(cacheKey);
59
+ }
60
+ catch {
61
+ // Pre-auth signing failed — invalidate and fall through
62
+ cache.delete(cacheKey);
63
+ }
64
+ }
65
+ // Normal flow: make request, handle 402 if needed
66
+ const clonedRequest = request.clone();
67
+ const response = await baseFetch(request);
68
+ if (response.status !== 402) {
69
+ return response;
70
+ }
71
+ // Parse 402 response and cache for future pre-auth
72
+ let paymentRequired;
73
+ try {
74
+ const getHeader = (name) => response.headers.get(name);
75
+ let body;
76
+ try {
77
+ const responseText = await Promise.race([
78
+ response.text(),
79
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Body read timeout")), 30_000)),
80
+ ]);
81
+ if (responseText)
82
+ body = JSON.parse(responseText);
83
+ }
84
+ catch {
85
+ /* empty body is fine */
86
+ }
87
+ paymentRequired = httpClient.getPaymentRequiredResponse(getHeader, body);
88
+ cache.set(cacheKey, { paymentRequired, cachedAt: Date.now() });
89
+ }
90
+ catch (error) {
91
+ throw new Error(`Failed to parse payment requirements: ${error instanceof Error ? error.message : "Unknown error"}`, { cause: error });
92
+ }
93
+ // Sign payment and retry
94
+ const payload = await client.createPaymentPayload(paymentRequired);
95
+ const paymentHeaders = httpClient.encodePaymentSignatureHeader(payload);
96
+ for (const [key, value] of Object.entries(paymentHeaders)) {
97
+ clonedRequest.headers.set(key, value);
98
+ }
99
+ return baseFetch(clonedRequest);
100
+ };
101
+ }
102
+ //# sourceMappingURL=payment-preauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment-preauth.js","sourceRoot":"","sources":["../src/payment-preauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * BlockRun ProviderPlugin for OpenClaw
3
+ *
4
+ * Registers BlockRun as an LLM provider in OpenClaw.
5
+ * Uses a local x402 proxy to handle micropayments transparently —
6
+ * pi-ai sees a standard OpenAI-compatible API at localhost.
7
+ */
8
+ import type { ProviderPlugin } from "./types.js";
9
+ import type { ProxyHandle } from "./proxy.js";
10
+ /**
11
+ * Update the proxy handle (called from index.ts when the proxy starts).
12
+ */
13
+ export declare function setActiveProxy(proxy: ProxyHandle): void;
14
+ export declare function getActiveProxy(): ProxyHandle | null;
15
+ /**
16
+ * BlockRun provider plugin definition.
17
+ */
18
+ export declare const blockrunProvider: ProviderPlugin;
19
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO9C;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAEvD;AAED,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAEnD;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAqB9B,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * BlockRun ProviderPlugin for OpenClaw
3
+ *
4
+ * Registers BlockRun as an LLM provider in OpenClaw.
5
+ * Uses a local x402 proxy to handle micropayments transparently —
6
+ * pi-ai sees a standard OpenAI-compatible API at localhost.
7
+ */
8
+ import { buildProviderModels } from "./models.js";
9
+ /**
10
+ * State for the running proxy (set when the plugin activates).
11
+ */
12
+ let activeProxy = null;
13
+ /**
14
+ * Update the proxy handle (called from index.ts when the proxy starts).
15
+ */
16
+ export function setActiveProxy(proxy) {
17
+ activeProxy = proxy;
18
+ }
19
+ export function getActiveProxy() {
20
+ return activeProxy;
21
+ }
22
+ /**
23
+ * BlockRun provider plugin definition.
24
+ */
25
+ export const blockrunProvider = {
26
+ id: "blockrun",
27
+ label: "BlockRun",
28
+ docsPath: "https://blockrun.ai/docs",
29
+ aliases: ["br"],
30
+ envVars: ["BLOCKRUN_WALLET_KEY"],
31
+ // Model definitions — dynamically set to proxy URL
32
+ get models() {
33
+ if (!activeProxy) {
34
+ // Fallback: point to BlockRun API directly (won't handle x402, but
35
+ // allows config loading before proxy starts)
36
+ return buildProviderModels("https://blockrun.ai/api");
37
+ }
38
+ return buildProviderModels(activeProxy.baseUrl);
39
+ },
40
+ // No auth required — the x402 proxy handles wallet-based payments internally.
41
+ // The proxy auto-generates a wallet on first run and stores it at
42
+ // ~/.openclaw/blockrun/wallet.key. Users just fund that wallet with USDC.
43
+ auth: [],
44
+ };
45
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD;;GAEG;AACH,IAAI,WAAW,GAAuB,IAAI,CAAC;AAE3C;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,WAAW,GAAG,KAAK,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAmB;IAC9C,EAAE,EAAE,UAAU;IACd,KAAK,EAAE,UAAU;IACjB,QAAQ,EAAE,0BAA0B;IACpC,OAAO,EAAE,CAAC,IAAI,CAAC;IACf,OAAO,EAAE,CAAC,qBAAqB,CAAC;IAEhC,mDAAmD;IACnD,IAAI,MAAM;QACR,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,mEAAmE;YACnE,6CAA6C;YAC7C,OAAO,mBAAmB,CAAC,yBAAyB,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,mBAAmB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,8EAA8E;IAC9E,kEAAkE;IAClE,0EAA0E;IAC1E,IAAI,EAAE,EAAE;CACT,CAAC"}
@@ -0,0 +1,210 @@
1
+ /**
2
+ * Local x402 Proxy Server
3
+ *
4
+ * Sits between OpenClaw's pi-ai (which makes standard OpenAI-format requests)
5
+ * and BlockRun's API (which requires x402 micropayments).
6
+ *
7
+ * Flow:
8
+ * pi-ai → http://localhost:{port}/v1/chat/completions
9
+ * → proxy forwards to https://blockrun.ai/api/v1/chat/completions
10
+ * → gets 402 → @x402/fetch signs payment → retries
11
+ * → streams response back to pi-ai
12
+ *
13
+ * Optimizations (v0.3.0):
14
+ * - SSE heartbeat: for streaming requests, sends headers + heartbeat immediately
15
+ * before the x402 flow, preventing OpenClaw's 10-15s timeout from firing.
16
+ * - Response dedup: hashes request bodies and caches responses for 30s,
17
+ * preventing double-charging when OpenClaw retries after timeout.
18
+ * - Smart routing: when model is "blockrun/auto", classify query and pick cheapest model.
19
+ * - Usage logging: log every request as JSON line to ~/.openclaw/blockrun/logs/
20
+ */
21
+ import { type RoutingDecision, type RoutingConfig } from "./router/index.js";
22
+ import { type ResponseCacheConfig } from "./response-cache.js";
23
+ import { BalanceMonitor } from "./balance.js";
24
+ import type { SolanaBalanceMonitor } from "./solana-balance.js";
25
+ /** Union type for chain-agnostic balance monitoring */
26
+ type AnyBalanceMonitor = BalanceMonitor | SolanaBalanceMonitor;
27
+ import { type SessionConfig } from "./session.js";
28
+ /**
29
+ * Semantic error categories from upstream provider responses.
30
+ * Used to distinguish auth failures from rate limits from server errors
31
+ * so each category can be handled independently without cross-contamination.
32
+ */
33
+ export type ErrorCategory = "auth_failure" | "quota_exceeded" | "rate_limited" | "overloaded" | "server_error" | "payment_error" | "config_error";
34
+ /**
35
+ * Classify an upstream error response into a semantic category.
36
+ * Returns null if the status+body is not a provider-side issue worth retrying.
37
+ */
38
+ export declare function categorizeError(status: number, body: string): ErrorCategory | null;
39
+ /**
40
+ * Get the proxy port from pre-loaded configuration.
41
+ * Port is validated at module load time, this just returns the cached value.
42
+ */
43
+ export declare function getProxyPort(): number;
44
+ /**
45
+ * Detect degraded 200-response payloads that should trigger model fallback.
46
+ * Returns a short reason when fallback should happen, otherwise undefined.
47
+ */
48
+ export declare function detectDegradedSuccessResponse(body: string): string | undefined;
49
+ type ChatMessage = {
50
+ role: string;
51
+ content: string | unknown;
52
+ };
53
+ /**
54
+ * Extended message type for thinking-enabled conversations.
55
+ */
56
+ type ExtendedChatMessage = ChatMessage & {
57
+ tool_calls?: unknown[];
58
+ reasoning_content?: unknown;
59
+ };
60
+ /**
61
+ * Normalize messages for thinking-enabled requests.
62
+ * When thinking/extended_thinking is enabled, ALL assistant messages in history
63
+ * must have reasoning_content (can be empty string if not present).
64
+ *
65
+ * Reasoning models like Kimi K2.5, DeepSeek-R1, etc. strip their thinking tokens
66
+ * before we forward the response to the client. So when the client sends back the
67
+ * assistant message in a follow-up turn, it lacks reasoning_content. These models
68
+ * reject the multi-turn history with 400 if any assistant message is missing it.
69
+ *
70
+ * Previously only tool-call messages were patched — this missed plain text assistant
71
+ * messages, causing 100% failures on existing (multi-turn) chats.
72
+ *
73
+ * Error examples:
74
+ * "400 thinking is enabled but reasoning_content is missing in assistant tool call message"
75
+ * "400 thinking is enabled but reasoning_content is missing in assistant message"
76
+ */
77
+ export declare function normalizeMessagesForThinking(messages: ExtendedChatMessage[]): ExtendedChatMessage[];
78
+ /**
79
+ * Remove "blockrun" branding from system messages before sending upstream.
80
+ *
81
+ * OpenClaw embeds `model=blockrun/auto` and `default_model=blockrun/auto` in its
82
+ * system prompt Runtime section. LLMs pick up "blockrun" and adopt it as their
83
+ * identity (e.g. "I'm Blockrun"), overriding the user's SOUL.md persona.
84
+ *
85
+ * This function replaces `blockrun/<profile>` references with the actual resolved
86
+ * model name, and strips any remaining "blockrun/" prefix so the upstream LLM
87
+ * never sees "blockrun" as an identity to adopt.
88
+ */
89
+ export declare function debrandSystemMessages(messages: ChatMessage[], resolvedModel: string): ChatMessage[];
90
+ /** Callback info for low balance warning */
91
+ export type LowBalanceInfo = {
92
+ balanceUSD: string;
93
+ walletAddress: string;
94
+ };
95
+ /** Callback info for insufficient funds error */
96
+ export type InsufficientFundsInfo = {
97
+ balanceUSD: string;
98
+ requiredUSD: string;
99
+ walletAddress: string;
100
+ };
101
+ /**
102
+ * Wallet config: either a plain EVM private key string, or the full
103
+ * resolution object from resolveOrGenerateWalletKey() which may include
104
+ * Solana keys. Using the full object prevents callers from accidentally
105
+ * forgetting to forward Solana key bytes.
106
+ */
107
+ export type WalletConfig = string | {
108
+ key: string;
109
+ solanaPrivateKeyBytes?: Uint8Array;
110
+ };
111
+ export type PaymentChain = "base" | "solana";
112
+ export type ProxyOptions = {
113
+ wallet: WalletConfig;
114
+ apiBase?: string;
115
+ /** Payment chain: "base" (default) or "solana". Can also be set via CLAWROUTER_PAYMENT_CHAIN env var. */
116
+ paymentChain?: PaymentChain;
117
+ /** Port to listen on (default: 8402) */
118
+ port?: number;
119
+ routingConfig?: Partial<RoutingConfig>;
120
+ /** Request timeout in ms (default: 180000 = 3 minutes). Covers on-chain tx + LLM response. */
121
+ requestTimeoutMs?: number;
122
+ /** Skip balance checks (for testing only). Default: false */
123
+ skipBalanceCheck?: boolean;
124
+ /** Override the balance monitor with a mock (for testing only). */
125
+ _balanceMonitorOverride?: AnyBalanceMonitor;
126
+ /**
127
+ * Session persistence config. When enabled, maintains model selection
128
+ * across requests within a session to prevent mid-task model switching.
129
+ */
130
+ sessionConfig?: Partial<SessionConfig>;
131
+ /**
132
+ * Auto-compress large requests to reduce network usage.
133
+ * When enabled, requests are automatically compressed using
134
+ * LLM-safe context compression (15-40% reduction).
135
+ * Default: true
136
+ */
137
+ autoCompressRequests?: boolean;
138
+ /**
139
+ * Threshold in KB to trigger auto-compression (default: 180).
140
+ * Requests larger than this are compressed before sending.
141
+ * Set to 0 to compress all requests.
142
+ */
143
+ compressionThresholdKB?: number;
144
+ /**
145
+ * Response caching config. When enabled, identical requests return
146
+ * cached responses instead of making new API calls.
147
+ * Default: enabled with 10 minute TTL, 200 max entries.
148
+ */
149
+ cacheConfig?: ResponseCacheConfig;
150
+ /**
151
+ * Maximum total spend (in USD) per session run.
152
+ * Default: undefined (no limit). Example: 0.5 = $0.50 per session.
153
+ */
154
+ maxCostPerRunUsd?: number;
155
+ /**
156
+ * How to enforce the per-run cost cap.
157
+ * - 'graceful' (default): when budget runs low, downgrade to cheaper models; use free model
158
+ * as last resort. Only hard-stops when no model can serve the request.
159
+ * - 'strict': immediately return 429 once the session spend reaches the cap.
160
+ */
161
+ maxCostPerRunMode?: "graceful" | "strict";
162
+ /**
163
+ * Set of model IDs to exclude from routing.
164
+ * Excluded models are filtered out of fallback chains.
165
+ * Loaded from ~/.openclaw/blockrun/exclude-models.json
166
+ */
167
+ excludeModels?: Set<string>;
168
+ onReady?: (port: number) => void;
169
+ onError?: (error: Error) => void;
170
+ onPayment?: (info: {
171
+ model: string;
172
+ amount: string;
173
+ network: string;
174
+ }) => void;
175
+ onRouted?: (decision: RoutingDecision) => void;
176
+ /** Called when balance drops below $1.00 (warning, request still proceeds) */
177
+ onLowBalance?: (info: LowBalanceInfo) => void;
178
+ /** Called when balance is insufficient for a request (request fails) */
179
+ onInsufficientFunds?: (info: InsufficientFundsInfo) => void;
180
+ };
181
+ export type ProxyHandle = {
182
+ port: number;
183
+ baseUrl: string;
184
+ walletAddress: string;
185
+ solanaAddress?: string;
186
+ balanceMonitor: AnyBalanceMonitor;
187
+ close: () => Promise<void>;
188
+ };
189
+ type ModelListEntry = {
190
+ id: string;
191
+ object: "model";
192
+ created: number;
193
+ owned_by: string;
194
+ };
195
+ /**
196
+ * Build `/v1/models` response entries from the full OpenClaw model registry.
197
+ * This includes alias IDs (e.g., `flash`, `kimi`) so `/model <alias>` works reliably.
198
+ */
199
+ export declare function buildProxyModelList(createdAt?: number): ModelListEntry[];
200
+ /**
201
+ * Start the local x402 proxy server.
202
+ *
203
+ * If a proxy is already running on the target port, reuses it instead of failing.
204
+ * Port can be configured via BLOCKRUN_PROXY_PORT environment variable.
205
+ *
206
+ * Returns a handle with the assigned port, base URL, and a close function.
207
+ */
208
+ export declare function startProxy(options: ProxyOptions): Promise<ProxyHandle>;
209
+ export {};
210
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAsBH,OAAO,EAUL,KAAK,eAAe,EACpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAC;AAe3B,OAAO,EAAiB,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,uDAAuD;AACvD,KAAK,iBAAiB,GAAG,cAAc,GAAG,oBAAoB,CAAC;AAO/D,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,cAAc,CAAC;AA2QtB;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,YAAY,GACZ,cAAc,GACd,eAAe,GACf,cAAc,CAAC;AAEnB;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAiBlF;AAqID;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAyHD;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAqE9E;AAiBD,KAAK,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAwM/D;;GAEG;AACH,KAAK,mBAAmB,GAAG,WAAW,GAAG;IACvC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,mBAAmB,EAAE,GAC9B,mBAAmB,EAAE,CAiBvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,WAAW,EAAE,EACvB,aAAa,EAAE,MAAM,GACpB,WAAW,EAAE,CA4Bf;AAsFD,4CAA4C;AAC5C,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,iDAAiD;AACjD,MAAM,MAAM,qBAAqB,GAAG;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,qBAAqB,CAAC,EAAE,UAAU,CAAA;CAAE,CAAC;AAExF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE7C,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yGAAyG;IACzG,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IACvC,8FAA8F;IAC9F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,mEAAmE;IACnE,uBAAuB,CAAC,EAAE,iBAAiB,CAAC;IAC5C;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IACvC;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC1C;;;;OAIG;IACH,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC/E,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAC9C,wEAAwE;IACxE,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC7D,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,iBAAiB,CAAC;IAClC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAmBF,KAAK,cAAc,GAAG;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,GAAE,MAAsC,GAChD,cAAc,EAAE,CAYlB;AAkOD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAuzB5E"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=proxy.debrand.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.debrand.test.d.ts","sourceRoot":"","sources":["../src/proxy.debrand.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,101 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { debrandSystemMessages } from "./proxy.js";
3
+ describe("debrandSystemMessages", () => {
4
+ it("replaces blockrun/auto with the resolved model in system messages", () => {
5
+ const messages = [
6
+ {
7
+ role: "system",
8
+ content: "You are a personal assistant.\n\n## Runtime\nRuntime: model=blockrun/auto | default_model=blockrun/auto",
9
+ },
10
+ { role: "user", content: "Hello" },
11
+ ];
12
+ const result = debrandSystemMessages(messages, "deepseek/deepseek-chat");
13
+ expect(result[0].content).toBe("You are a personal assistant.\n\n## Runtime\nRuntime: model=deepseek/deepseek-chat | default_model=deepseek/deepseek-chat");
14
+ // User message untouched
15
+ expect(result[1].content).toBe("Hello");
16
+ });
17
+ it("replaces blockrun/eco and blockrun/premium profiles", () => {
18
+ const messages = [
19
+ {
20
+ role: "system",
21
+ content: "model=blockrun/eco | default_model=blockrun/premium",
22
+ },
23
+ ];
24
+ const result = debrandSystemMessages(messages, "google/gemini-2.5-flash");
25
+ expect(result[0].content).toBe("model=google/gemini-2.5-flash | default_model=google/gemini-2.5-flash");
26
+ });
27
+ it("strips blockrun/ prefix from explicit model names", () => {
28
+ const messages = [
29
+ {
30
+ role: "system",
31
+ content: "model=blockrun/openai/gpt-4o | default_model=blockrun/auto",
32
+ },
33
+ ];
34
+ const result = debrandSystemMessages(messages, "openai/gpt-4o");
35
+ expect(result[0].content).toBe("model=openai/gpt-4o | default_model=openai/gpt-4o");
36
+ });
37
+ it("does not modify non-system messages", () => {
38
+ const messages = [
39
+ { role: "user", content: "I use blockrun/auto for my tasks" },
40
+ { role: "assistant", content: "I'm Blockrun!" },
41
+ ];
42
+ const result = debrandSystemMessages(messages, "deepseek/deepseek-chat");
43
+ expect(result[0].content).toBe("I use blockrun/auto for my tasks");
44
+ expect(result[1].content).toBe("I'm Blockrun!");
45
+ });
46
+ it("returns same array reference when no changes needed", () => {
47
+ const messages = [
48
+ { role: "system", content: "You are a helpful assistant." },
49
+ { role: "user", content: "Hi" },
50
+ ];
51
+ const result = debrandSystemMessages(messages, "deepseek/deepseek-chat");
52
+ expect(result).toBe(messages); // same reference = no copy
53
+ });
54
+ it("handles non-string system content gracefully", () => {
55
+ const messages = [{ role: "system", content: [{ type: "text", text: "blockrun/auto" }] }];
56
+ const result = debrandSystemMessages(messages, "deepseek/deepseek-chat");
57
+ // Array content is not modified (only string content)
58
+ expect(result).toBe(messages);
59
+ });
60
+ it("is case-insensitive for blockrun prefix", () => {
61
+ const messages = [{ role: "system", content: "model=Blockrun/Auto" }];
62
+ const result = debrandSystemMessages(messages, "deepseek/deepseek-chat");
63
+ expect(result[0].content).toBe("model=deepseek/deepseek-chat");
64
+ });
65
+ it("replaces blockrun/free profile", () => {
66
+ const messages = [{ role: "system", content: "default_model=blockrun/free" }];
67
+ const result = debrandSystemMessages(messages, "nvidia/gpt-oss-120b");
68
+ expect(result[0].content).toBe("default_model=nvidia/gpt-oss-120b");
69
+ });
70
+ it("handles realistic OpenClaw system prompt with SOUL.md", () => {
71
+ // This simulates the actual system prompt OpenClaw generates,
72
+ // which caused the model to say "I'm Blockrun" (issue #99)
73
+ const systemContent = [
74
+ "You are a personal assistant running inside OpenClaw.",
75
+ "",
76
+ "## Runtime",
77
+ "Runtime: agent=main | host=openclaw | os=Darwin 25.3.0 (arm64) | node=v22.14.0 | model=blockrun/auto | default_model=blockrun/auto | channel=control-ui | thinking=off",
78
+ "",
79
+ "# Project Context",
80
+ "",
81
+ "## SOUL.md",
82
+ "",
83
+ "AIBot = Watson",
84
+ "User = Fred",
85
+ ].join("\n");
86
+ const messages = [
87
+ { role: "system", content: systemContent },
88
+ { role: "user", content: "Hey there!" },
89
+ ];
90
+ const result = debrandSystemMessages(messages, "deepseek/deepseek-chat");
91
+ // "blockrun" should be completely gone from system prompt
92
+ expect(result[0].content).not.toContain("blockrun");
93
+ // Resolved model should appear instead
94
+ expect(result[0].content).toContain("model=deepseek/deepseek-chat");
95
+ expect(result[0].content).toContain("default_model=deepseek/deepseek-chat");
96
+ // SOUL.md content should be preserved
97
+ expect(result[0].content).toContain("AIBot = Watson");
98
+ expect(result[0].content).toContain("User = Fred");
99
+ });
100
+ });
101
+ //# sourceMappingURL=proxy.debrand.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.debrand.test.js","sourceRoot":"","sources":["../src/proxy.debrand.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=proxy.degraded-response.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.degraded-response.test.d.ts","sourceRoot":"","sources":["../src/proxy.degraded-response.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,105 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { detectDegradedSuccessResponse } from "./proxy.js";
3
+ describe("detectDegradedSuccessResponse", () => {
4
+ it("flags plain overload placeholder text", () => {
5
+ const result = detectDegradedSuccessResponse("The AI service is temporarily overloaded. Please try again in a moment.");
6
+ expect(result).toBeDefined();
7
+ });
8
+ it("flags overload placeholder inside successful chat response JSON", () => {
9
+ const payload = JSON.stringify({
10
+ choices: [
11
+ {
12
+ message: {
13
+ role: "assistant",
14
+ content: "The AI service is temporarily overloaded. Please try again in a moment.",
15
+ },
16
+ },
17
+ ],
18
+ });
19
+ const result = detectDegradedSuccessResponse(payload);
20
+ expect(result).toBeDefined();
21
+ });
22
+ it("flags known repetitive hallucination loop patterns", () => {
23
+ const payload = JSON.stringify({
24
+ choices: [
25
+ {
26
+ message: {
27
+ role: "assistant",
28
+ content: `The boxed is the response.
29
+
30
+ Yes.
31
+
32
+ The response is the text.
33
+
34
+ Yes.
35
+
36
+ The final answer is the boxed.
37
+
38
+ Yes.`,
39
+ },
40
+ },
41
+ ],
42
+ });
43
+ const result = detectDegradedSuccessResponse(payload);
44
+ expect(result).toBeDefined();
45
+ });
46
+ it("flags empty turn: no content and no tool_calls with finish_reason stop", () => {
47
+ const payload = JSON.stringify({
48
+ choices: [
49
+ {
50
+ message: { role: "assistant", content: "" },
51
+ finish_reason: "stop",
52
+ },
53
+ ],
54
+ });
55
+ const result = detectDegradedSuccessResponse(payload);
56
+ expect(result).toMatch(/empty turn/);
57
+ });
58
+ it("flags empty turn: null content, no tool_calls, finish_reason stop", () => {
59
+ const payload = JSON.stringify({
60
+ choices: [{ message: { role: "assistant", content: null }, finish_reason: "stop" }],
61
+ });
62
+ const result = detectDegradedSuccessResponse(payload);
63
+ expect(result).toMatch(/empty turn/);
64
+ });
65
+ it("does not flag responses with tool_calls even if content is empty", () => {
66
+ const payload = JSON.stringify({
67
+ choices: [
68
+ {
69
+ message: {
70
+ role: "assistant",
71
+ content: null,
72
+ tool_calls: [
73
+ { id: "call_1", type: "function", function: { name: "read_file", arguments: "{}" } },
74
+ ],
75
+ },
76
+ finish_reason: "tool_calls",
77
+ },
78
+ ],
79
+ });
80
+ const result = detectDegradedSuccessResponse(payload);
81
+ expect(result).toBeUndefined();
82
+ });
83
+ it("does not flag empty turn when finish_reason is not stop", () => {
84
+ const payload = JSON.stringify({
85
+ choices: [{ message: { role: "assistant", content: "" }, finish_reason: "length" }],
86
+ });
87
+ const result = detectDegradedSuccessResponse(payload);
88
+ expect(result).toBeUndefined();
89
+ });
90
+ it("does not flag normal assistant responses", () => {
91
+ const payload = JSON.stringify({
92
+ choices: [
93
+ {
94
+ message: {
95
+ role: "assistant",
96
+ content: "Paris is the capital of France.",
97
+ },
98
+ },
99
+ ],
100
+ });
101
+ const result = detectDegradedSuccessResponse(payload);
102
+ expect(result).toBeUndefined();
103
+ });
104
+ });
105
+ //# sourceMappingURL=proxy.degraded-response.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.degraded-response.test.js","sourceRoot":"","sources":["../src/proxy.degraded-response.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=proxy.image-download.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.image-download.test.d.ts","sourceRoot":"","sources":["../src/proxy.image-download.test.ts"],"names":[],"mappings":""}