@blockrun/clawrouter 0.12.93 → 0.12.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +133 -54
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +75 -54
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -18721,7 +18721,7 @@ var require_permessage_deflate = __commonJS({
|
|
|
18721
18721
|
var kBuffers = /* @__PURE__ */ Symbol("buffers");
|
|
18722
18722
|
var kError = /* @__PURE__ */ Symbol("error");
|
|
18723
18723
|
var zlibLimiter;
|
|
18724
|
-
var
|
|
18724
|
+
var PerMessageDeflate2 = class {
|
|
18725
18725
|
/**
|
|
18726
18726
|
* Creates a PerMessageDeflate instance.
|
|
18727
18727
|
*
|
|
@@ -18732,6 +18732,9 @@ var require_permessage_deflate = __commonJS({
|
|
|
18732
18732
|
* acknowledge disabling of client context takeover
|
|
18733
18733
|
* @param {Number} [options.concurrencyLimit=10] The number of concurrent
|
|
18734
18734
|
* calls to zlib
|
|
18735
|
+
* @param {Boolean} [options.isServer=false] Create the instance in either
|
|
18736
|
+
* server or client mode
|
|
18737
|
+
* @param {Number} [options.maxPayload=0] The maximum allowed message length
|
|
18735
18738
|
* @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the
|
|
18736
18739
|
* use of a custom server window size
|
|
18737
18740
|
* @param {Boolean} [options.serverNoContextTakeover=false] Request/accept
|
|
@@ -18742,15 +18745,12 @@ var require_permessage_deflate = __commonJS({
|
|
|
18742
18745
|
* deflate
|
|
18743
18746
|
* @param {Object} [options.zlibInflateOptions] Options to pass to zlib on
|
|
18744
18747
|
* inflate
|
|
18745
|
-
* @param {Boolean} [isServer=false] Create the instance in either server or
|
|
18746
|
-
* client mode
|
|
18747
|
-
* @param {Number} [maxPayload=0] The maximum allowed message length
|
|
18748
18748
|
*/
|
|
18749
|
-
constructor(options
|
|
18750
|
-
this._maxPayload = maxPayload | 0;
|
|
18749
|
+
constructor(options) {
|
|
18751
18750
|
this._options = options || {};
|
|
18752
18751
|
this._threshold = this._options.threshold !== void 0 ? this._options.threshold : 1024;
|
|
18753
|
-
this.
|
|
18752
|
+
this._maxPayload = this._options.maxPayload | 0;
|
|
18753
|
+
this._isServer = !!this._options.isServer;
|
|
18754
18754
|
this._deflate = null;
|
|
18755
18755
|
this._inflate = null;
|
|
18756
18756
|
this.params = null;
|
|
@@ -19059,7 +19059,7 @@ var require_permessage_deflate = __commonJS({
|
|
|
19059
19059
|
});
|
|
19060
19060
|
}
|
|
19061
19061
|
};
|
|
19062
|
-
module.exports =
|
|
19062
|
+
module.exports = PerMessageDeflate2;
|
|
19063
19063
|
function deflateOnData(chunk) {
|
|
19064
19064
|
this[kBuffers].push(chunk);
|
|
19065
19065
|
this[kTotalLength] += chunk.length;
|
|
@@ -19294,7 +19294,7 @@ var require_receiver = __commonJS({
|
|
|
19294
19294
|
"node_modules/ws/lib/receiver.js"(exports, module) {
|
|
19295
19295
|
"use strict";
|
|
19296
19296
|
var { Writable } = __require("stream");
|
|
19297
|
-
var
|
|
19297
|
+
var PerMessageDeflate2 = require_permessage_deflate();
|
|
19298
19298
|
var {
|
|
19299
19299
|
BINARY_TYPES,
|
|
19300
19300
|
EMPTY_BUFFER,
|
|
@@ -19461,7 +19461,7 @@ var require_receiver = __commonJS({
|
|
|
19461
19461
|
return;
|
|
19462
19462
|
}
|
|
19463
19463
|
const compressed = (buf[0] & 64) === 64;
|
|
19464
|
-
if (compressed && !this._extensions[
|
|
19464
|
+
if (compressed && !this._extensions[PerMessageDeflate2.extensionName]) {
|
|
19465
19465
|
const error = this.createError(
|
|
19466
19466
|
RangeError,
|
|
19467
19467
|
"RSV1 must be clear",
|
|
@@ -19705,7 +19705,7 @@ var require_receiver = __commonJS({
|
|
|
19705
19705
|
* @private
|
|
19706
19706
|
*/
|
|
19707
19707
|
decompress(data, cb) {
|
|
19708
|
-
const perMessageDeflate = this._extensions[
|
|
19708
|
+
const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName];
|
|
19709
19709
|
perMessageDeflate.decompress(data, this._fin, (err, buf) => {
|
|
19710
19710
|
if (err) return cb(err);
|
|
19711
19711
|
if (buf.length) {
|
|
@@ -19887,7 +19887,7 @@ var require_sender = __commonJS({
|
|
|
19887
19887
|
"use strict";
|
|
19888
19888
|
var { Duplex } = __require("stream");
|
|
19889
19889
|
var { randomFillSync } = __require("crypto");
|
|
19890
|
-
var
|
|
19890
|
+
var PerMessageDeflate2 = require_permessage_deflate();
|
|
19891
19891
|
var { EMPTY_BUFFER, kWebSocket, NOOP } = require_constants();
|
|
19892
19892
|
var { isBlob, isValidStatusCode } = require_validation();
|
|
19893
19893
|
var { mask: applyMask, toBuffer } = require_buffer_util();
|
|
@@ -20171,7 +20171,7 @@ var require_sender = __commonJS({
|
|
|
20171
20171
|
* @public
|
|
20172
20172
|
*/
|
|
20173
20173
|
send(data, options, cb) {
|
|
20174
|
-
const perMessageDeflate = this._extensions[
|
|
20174
|
+
const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName];
|
|
20175
20175
|
let opcode = options.binary ? 2 : 1;
|
|
20176
20176
|
let rsv1 = options.compress;
|
|
20177
20177
|
let byteLength;
|
|
@@ -20295,7 +20295,7 @@ var require_sender = __commonJS({
|
|
|
20295
20295
|
this.sendFrame(_Sender.frame(data, options), cb);
|
|
20296
20296
|
return;
|
|
20297
20297
|
}
|
|
20298
|
-
const perMessageDeflate = this._extensions[
|
|
20298
|
+
const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName];
|
|
20299
20299
|
this._bufferedBytes += options[kByteLength];
|
|
20300
20300
|
this._state = DEFLATING;
|
|
20301
20301
|
perMessageDeflate.compress(data, options.fin, (_, buf) => {
|
|
@@ -20733,11 +20733,11 @@ var require_extension = __commonJS({
|
|
|
20733
20733
|
return offers;
|
|
20734
20734
|
}
|
|
20735
20735
|
function format(extensions) {
|
|
20736
|
-
return Object.keys(extensions).map((
|
|
20737
|
-
let configurations = extensions[
|
|
20736
|
+
return Object.keys(extensions).map((extension2) => {
|
|
20737
|
+
let configurations = extensions[extension2];
|
|
20738
20738
|
if (!Array.isArray(configurations)) configurations = [configurations];
|
|
20739
20739
|
return configurations.map((params) => {
|
|
20740
|
-
return [
|
|
20740
|
+
return [extension2].concat(
|
|
20741
20741
|
Object.keys(params).map((k) => {
|
|
20742
20742
|
let values = params[k];
|
|
20743
20743
|
if (!Array.isArray(values)) values = [values];
|
|
@@ -20763,7 +20763,7 @@ var require_websocket = __commonJS({
|
|
|
20763
20763
|
var { randomBytes: randomBytes3, createHash: createHash4 } = __require("crypto");
|
|
20764
20764
|
var { Duplex, Readable } = __require("stream");
|
|
20765
20765
|
var { URL: URL2 } = __require("url");
|
|
20766
|
-
var
|
|
20766
|
+
var PerMessageDeflate2 = require_permessage_deflate();
|
|
20767
20767
|
var Receiver2 = require_receiver();
|
|
20768
20768
|
var Sender2 = require_sender();
|
|
20769
20769
|
var { isBlob } = require_validation();
|
|
@@ -20971,8 +20971,8 @@ var require_websocket = __commonJS({
|
|
|
20971
20971
|
this.emit("close", this._closeCode, this._closeMessage);
|
|
20972
20972
|
return;
|
|
20973
20973
|
}
|
|
20974
|
-
if (this._extensions[
|
|
20975
|
-
this._extensions[
|
|
20974
|
+
if (this._extensions[PerMessageDeflate2.extensionName]) {
|
|
20975
|
+
this._extensions[PerMessageDeflate2.extensionName].cleanup();
|
|
20976
20976
|
}
|
|
20977
20977
|
this._receiver.removeAllListeners();
|
|
20978
20978
|
this._readyState = _WebSocket.CLOSED;
|
|
@@ -21134,7 +21134,7 @@ var require_websocket = __commonJS({
|
|
|
21134
21134
|
fin: true,
|
|
21135
21135
|
...options
|
|
21136
21136
|
};
|
|
21137
|
-
if (!this._extensions[
|
|
21137
|
+
if (!this._extensions[PerMessageDeflate2.extensionName]) {
|
|
21138
21138
|
opts.compress = false;
|
|
21139
21139
|
}
|
|
21140
21140
|
this._sender.send(data || EMPTY_BUFFER, opts, cb);
|
|
@@ -21260,7 +21260,7 @@ var require_websocket = __commonJS({
|
|
|
21260
21260
|
} else {
|
|
21261
21261
|
try {
|
|
21262
21262
|
parsedUrl = new URL2(address2);
|
|
21263
|
-
} catch
|
|
21263
|
+
} catch {
|
|
21264
21264
|
throw new SyntaxError(`Invalid URL: ${address2}`);
|
|
21265
21265
|
}
|
|
21266
21266
|
}
|
|
@@ -21308,13 +21308,13 @@ var require_websocket = __commonJS({
|
|
|
21308
21308
|
opts.path = parsedUrl.pathname + parsedUrl.search;
|
|
21309
21309
|
opts.timeout = opts.handshakeTimeout;
|
|
21310
21310
|
if (opts.perMessageDeflate) {
|
|
21311
|
-
perMessageDeflate = new
|
|
21312
|
-
opts.perMessageDeflate
|
|
21313
|
-
false,
|
|
21314
|
-
opts.maxPayload
|
|
21315
|
-
);
|
|
21311
|
+
perMessageDeflate = new PerMessageDeflate2({
|
|
21312
|
+
...opts.perMessageDeflate,
|
|
21313
|
+
isServer: false,
|
|
21314
|
+
maxPayload: opts.maxPayload
|
|
21315
|
+
});
|
|
21316
21316
|
opts.headers["Sec-WebSocket-Extensions"] = format({
|
|
21317
|
-
[
|
|
21317
|
+
[PerMessageDeflate2.extensionName]: perMessageDeflate.offer()
|
|
21318
21318
|
});
|
|
21319
21319
|
}
|
|
21320
21320
|
if (protocols.length) {
|
|
@@ -21457,19 +21457,19 @@ var require_websocket = __commonJS({
|
|
|
21457
21457
|
return;
|
|
21458
21458
|
}
|
|
21459
21459
|
const extensionNames = Object.keys(extensions);
|
|
21460
|
-
if (extensionNames.length !== 1 || extensionNames[0] !==
|
|
21460
|
+
if (extensionNames.length !== 1 || extensionNames[0] !== PerMessageDeflate2.extensionName) {
|
|
21461
21461
|
const message = "Server indicated an extension that was not requested";
|
|
21462
21462
|
abortHandshake(websocket, socket, message);
|
|
21463
21463
|
return;
|
|
21464
21464
|
}
|
|
21465
21465
|
try {
|
|
21466
|
-
perMessageDeflate.accept(extensions[
|
|
21466
|
+
perMessageDeflate.accept(extensions[PerMessageDeflate2.extensionName]);
|
|
21467
21467
|
} catch (err) {
|
|
21468
21468
|
const message = "Invalid Sec-WebSocket-Extensions header";
|
|
21469
21469
|
abortHandshake(websocket, socket, message);
|
|
21470
21470
|
return;
|
|
21471
21471
|
}
|
|
21472
|
-
websocket._extensions[
|
|
21472
|
+
websocket._extensions[PerMessageDeflate2.extensionName] = perMessageDeflate;
|
|
21473
21473
|
}
|
|
21474
21474
|
websocket.setSocket(socket, head, {
|
|
21475
21475
|
allowSynchronousEvents: opts.allowSynchronousEvents,
|
|
@@ -21788,9 +21788,9 @@ var require_websocket_server = __commonJS({
|
|
|
21788
21788
|
var http2 = __require("http");
|
|
21789
21789
|
var { Duplex } = __require("stream");
|
|
21790
21790
|
var { createHash: createHash4 } = __require("crypto");
|
|
21791
|
-
var
|
|
21792
|
-
var
|
|
21793
|
-
var
|
|
21791
|
+
var extension2 = require_extension();
|
|
21792
|
+
var PerMessageDeflate2 = require_permessage_deflate();
|
|
21793
|
+
var subprotocol2 = require_subprotocol();
|
|
21794
21794
|
var WebSocket2 = require_websocket();
|
|
21795
21795
|
var { CLOSE_TIMEOUT, GUID, kWebSocket } = require_constants();
|
|
21796
21796
|
var keyRegex = /^[+/0-9A-Za-z]{22}==$/;
|
|
@@ -22013,7 +22013,7 @@ var require_websocket_server = __commonJS({
|
|
|
22013
22013
|
let protocols = /* @__PURE__ */ new Set();
|
|
22014
22014
|
if (secWebSocketProtocol !== void 0) {
|
|
22015
22015
|
try {
|
|
22016
|
-
protocols =
|
|
22016
|
+
protocols = subprotocol2.parse(secWebSocketProtocol);
|
|
22017
22017
|
} catch (err) {
|
|
22018
22018
|
const message = "Invalid Sec-WebSocket-Protocol header";
|
|
22019
22019
|
abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
|
|
@@ -22023,16 +22023,16 @@ var require_websocket_server = __commonJS({
|
|
|
22023
22023
|
const secWebSocketExtensions = req.headers["sec-websocket-extensions"];
|
|
22024
22024
|
const extensions = {};
|
|
22025
22025
|
if (this.options.perMessageDeflate && secWebSocketExtensions !== void 0) {
|
|
22026
|
-
const perMessageDeflate = new
|
|
22027
|
-
this.options.perMessageDeflate,
|
|
22028
|
-
true,
|
|
22029
|
-
this.options.maxPayload
|
|
22030
|
-
);
|
|
22026
|
+
const perMessageDeflate = new PerMessageDeflate2({
|
|
22027
|
+
...this.options.perMessageDeflate,
|
|
22028
|
+
isServer: true,
|
|
22029
|
+
maxPayload: this.options.maxPayload
|
|
22030
|
+
});
|
|
22031
22031
|
try {
|
|
22032
|
-
const offers =
|
|
22033
|
-
if (offers[
|
|
22034
|
-
perMessageDeflate.accept(offers[
|
|
22035
|
-
extensions[
|
|
22032
|
+
const offers = extension2.parse(secWebSocketExtensions);
|
|
22033
|
+
if (offers[PerMessageDeflate2.extensionName]) {
|
|
22034
|
+
perMessageDeflate.accept(offers[PerMessageDeflate2.extensionName]);
|
|
22035
|
+
extensions[PerMessageDeflate2.extensionName] = perMessageDeflate;
|
|
22036
22036
|
}
|
|
22037
22037
|
} catch (err) {
|
|
22038
22038
|
const message = "Invalid or unacceptable Sec-WebSocket-Extensions header";
|
|
@@ -22103,10 +22103,10 @@ var require_websocket_server = __commonJS({
|
|
|
22103
22103
|
ws._protocol = protocol;
|
|
22104
22104
|
}
|
|
22105
22105
|
}
|
|
22106
|
-
if (extensions[
|
|
22107
|
-
const params = extensions[
|
|
22108
|
-
const value =
|
|
22109
|
-
[
|
|
22106
|
+
if (extensions[PerMessageDeflate2.extensionName]) {
|
|
22107
|
+
const params = extensions[PerMessageDeflate2.extensionName].params;
|
|
22108
|
+
const value = extension2.format({
|
|
22109
|
+
[PerMessageDeflate2.extensionName]: [params]
|
|
22110
22110
|
});
|
|
22111
22111
|
headers.push(`Sec-WebSocket-Extensions: ${value}`);
|
|
22112
22112
|
ws._extensions = extensions;
|
|
@@ -22174,13 +22174,16 @@ var require_websocket_server = __commonJS({
|
|
|
22174
22174
|
});
|
|
22175
22175
|
|
|
22176
22176
|
// node_modules/ws/wrapper.mjs
|
|
22177
|
-
var import_stream, import_receiver, import_sender, import_websocket, import_websocket_server, wrapper_default;
|
|
22177
|
+
var import_stream, import_extension, import_permessage_deflate, import_receiver, import_sender, import_subprotocol, import_websocket, import_websocket_server, wrapper_default;
|
|
22178
22178
|
var init_wrapper = __esm({
|
|
22179
22179
|
"node_modules/ws/wrapper.mjs"() {
|
|
22180
22180
|
"use strict";
|
|
22181
22181
|
import_stream = __toESM(require_stream(), 1);
|
|
22182
|
+
import_extension = __toESM(require_extension(), 1);
|
|
22183
|
+
import_permessage_deflate = __toESM(require_permessage_deflate(), 1);
|
|
22182
22184
|
import_receiver = __toESM(require_receiver(), 1);
|
|
22183
22185
|
import_sender = __toESM(require_sender(), 1);
|
|
22186
|
+
import_subprotocol = __toESM(require_subprotocol(), 1);
|
|
22184
22187
|
import_websocket = __toESM(require_websocket(), 1);
|
|
22185
22188
|
import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
22186
22189
|
wrapper_default = import_websocket.default;
|
|
@@ -41867,8 +41870,8 @@ var x402Client = class _x402Client {
|
|
|
41867
41870
|
* @param extension - The client extension to register
|
|
41868
41871
|
* @returns The x402Client instance for chaining
|
|
41869
41872
|
*/
|
|
41870
|
-
registerExtension(
|
|
41871
|
-
this.registeredExtensions.set(
|
|
41873
|
+
registerExtension(extension2) {
|
|
41874
|
+
this.registeredExtensions.set(extension2.key, extension2);
|
|
41872
41875
|
return this;
|
|
41873
41876
|
}
|
|
41874
41877
|
/**
|
|
@@ -42014,9 +42017,9 @@ var x402Client = class _x402Client {
|
|
|
42014
42017
|
return paymentPayload;
|
|
42015
42018
|
}
|
|
42016
42019
|
let enriched = paymentPayload;
|
|
42017
|
-
for (const [key,
|
|
42018
|
-
if (key in paymentRequired.extensions &&
|
|
42019
|
-
enriched = await
|
|
42020
|
+
for (const [key, extension2] of this.registeredExtensions) {
|
|
42021
|
+
if (key in paymentRequired.extensions && extension2.enrichPaymentPayload) {
|
|
42022
|
+
enriched = await extension2.enrichPaymentPayload(enriched, paymentRequired);
|
|
42020
42023
|
}
|
|
42021
42024
|
}
|
|
42022
42025
|
return enriched;
|
|
@@ -45644,6 +45647,48 @@ async function getStats(days = 7) {
|
|
|
45644
45647
|
// How many entries have valid baseline tracking
|
|
45645
45648
|
};
|
|
45646
45649
|
}
|
|
45650
|
+
async function formatRecentLogs(days = 1) {
|
|
45651
|
+
const logFiles = await getLogFiles();
|
|
45652
|
+
const filesToRead = logFiles.slice(0, days);
|
|
45653
|
+
const allEntries = [];
|
|
45654
|
+
for (const file of filesToRead) {
|
|
45655
|
+
const entries = await parseLogFile(join4(LOG_DIR2, file));
|
|
45656
|
+
allEntries.push(...entries);
|
|
45657
|
+
}
|
|
45658
|
+
allEntries.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
45659
|
+
const lines = [];
|
|
45660
|
+
lines.push("\u2554\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
|
|
45661
|
+
lines.push(`\u2551 ClawRouter Request Log \u2014 last ${days === 1 ? "24h" : `${days} days`}`.padEnd(72) + "\u2551");
|
|
45662
|
+
lines.push("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2566\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\u2566\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2566\u2550\u2550\u2550\u2550\u2550\u2550\u2566\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563");
|
|
45663
|
+
lines.push("\u2551 Time \u2551 Model \u2551 Cost \u2551 ms \u2551 Status \u2551");
|
|
45664
|
+
lines.push("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256C\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\u256C\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256C\u2550\u2550\u2550\u2550\u2550\u2550\u256C\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563");
|
|
45665
|
+
if (allEntries.length === 0) {
|
|
45666
|
+
lines.push("\u2551 No requests found".padEnd(72) + "\u2551");
|
|
45667
|
+
}
|
|
45668
|
+
let totalCost = 0;
|
|
45669
|
+
for (const e7 of allEntries) {
|
|
45670
|
+
const time = e7.timestamp.slice(11, 19);
|
|
45671
|
+
const date = e7.timestamp.slice(5, 10);
|
|
45672
|
+
const displayTime = `${date} ${time}`;
|
|
45673
|
+
const model = e7.model.length > 24 ? e7.model.slice(0, 21) + "..." : e7.model;
|
|
45674
|
+
const cost = `$${e7.cost.toFixed(4)}`;
|
|
45675
|
+
const ms = e7.latencyMs > 9999 ? `${(e7.latencyMs / 1e3).toFixed(1)}s` : `${e7.latencyMs}ms`;
|
|
45676
|
+
const status = e7.status === "error" ? " ERROR " : " OK ";
|
|
45677
|
+
totalCost += e7.cost;
|
|
45678
|
+
lines.push(
|
|
45679
|
+
`\u2551 ${displayTime.padEnd(16)}\u2551 ${model.padEnd(24)}\u2551 ${cost.padStart(7)}\u2551 ${ms.padStart(4)}\u2551${status}\u2551`
|
|
45680
|
+
);
|
|
45681
|
+
}
|
|
45682
|
+
lines.push("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2569\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\u2569\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2569\u2550\u2550\u2550\u2550\u2550\u2550\u2569\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563");
|
|
45683
|
+
lines.push(
|
|
45684
|
+
`\u2551 ${allEntries.length} request${allEntries.length !== 1 ? "s" : ""} Total spent: $${totalCost.toFixed(4)}`.padEnd(72) + "\u2551"
|
|
45685
|
+
);
|
|
45686
|
+
lines.push(
|
|
45687
|
+
"\u2551 Logs: ~/.openclaw/blockrun/logs/ (JSONL \u2014 one entry per request)".padEnd(72) + "\u2551"
|
|
45688
|
+
);
|
|
45689
|
+
lines.push("\u255A\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
|
|
45690
|
+
return lines.join("\n");
|
|
45691
|
+
}
|
|
45647
45692
|
async function clearStats() {
|
|
45648
45693
|
try {
|
|
45649
45694
|
const files = await readdir(LOG_DIR2);
|
|
@@ -52439,6 +52484,7 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
52439
52484
|
let accumulatedContent = "";
|
|
52440
52485
|
let responseInputTokens;
|
|
52441
52486
|
let responseOutputTokens;
|
|
52487
|
+
let requestHadError = false;
|
|
52442
52488
|
const isChatCompletion = req.url?.includes("/chat/completions");
|
|
52443
52489
|
const sessionId = getSessionId(req.headers);
|
|
52444
52490
|
let effectiveSessionId = sessionId;
|
|
@@ -53703,6 +53749,7 @@ data: [DONE]
|
|
|
53703
53749
|
const rawErrBody = lastError?.body || structuredMessage;
|
|
53704
53750
|
const errStatus = lastError?.status || 502;
|
|
53705
53751
|
const transformedErr = transformPaymentError(rawErrBody);
|
|
53752
|
+
requestHadError = true;
|
|
53706
53753
|
if (headersSentEarly) {
|
|
53707
53754
|
let errPayload;
|
|
53708
53755
|
try {
|
|
@@ -53746,6 +53793,21 @@ data: [DONE]
|
|
|
53746
53793
|
completedAt: Date.now()
|
|
53747
53794
|
});
|
|
53748
53795
|
}
|
|
53796
|
+
const errModel = routingDecision?.model ?? modelId;
|
|
53797
|
+
if (errModel) {
|
|
53798
|
+
const errPayment = paymentStore.getStore()?.amountUsd ?? 0;
|
|
53799
|
+
logUsage({
|
|
53800
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
53801
|
+
model: errModel,
|
|
53802
|
+
tier: routingDecision?.tier ?? "DIRECT",
|
|
53803
|
+
cost: errPayment,
|
|
53804
|
+
baselineCost: errPayment,
|
|
53805
|
+
savings: 0,
|
|
53806
|
+
latencyMs: Date.now() - startTime,
|
|
53807
|
+
status: "error"
|
|
53808
|
+
}).catch(() => {
|
|
53809
|
+
});
|
|
53810
|
+
}
|
|
53749
53811
|
return;
|
|
53750
53812
|
}
|
|
53751
53813
|
const responseChunks = [];
|
|
@@ -54080,6 +54142,7 @@ data: [DONE]
|
|
|
54080
54142
|
baselineCost: logBaseline,
|
|
54081
54143
|
savings: logSavings,
|
|
54082
54144
|
latencyMs: Date.now() - startTime,
|
|
54145
|
+
status: requestHadError ? "error" : "success",
|
|
54083
54146
|
...responseInputTokens !== void 0 && { inputTokens: responseInputTokens },
|
|
54084
54147
|
...responseOutputTokens !== void 0 && { outputTokens: responseOutputTokens }
|
|
54085
54148
|
};
|
|
@@ -54692,6 +54755,7 @@ Usage:
|
|
|
54692
54755
|
clawrouter doctor [opus] [question]
|
|
54693
54756
|
clawrouter partners [test]
|
|
54694
54757
|
clawrouter report [daily|weekly|monthly] [--json]
|
|
54758
|
+
clawrouter logs [--days <n>]
|
|
54695
54759
|
|
|
54696
54760
|
Options:
|
|
54697
54761
|
--version, -v Show version number
|
|
@@ -54701,6 +54765,8 @@ Options:
|
|
|
54701
54765
|
Commands:
|
|
54702
54766
|
doctor AI-powered diagnostics (default: Sonnet ~$0.003)
|
|
54703
54767
|
doctor opus Use Opus for deeper analysis (~$0.01)
|
|
54768
|
+
logs Per-request breakdown: model, cost, latency, status
|
|
54769
|
+
logs --days 7 Show last 7 days of requests (default: 1 day)
|
|
54704
54770
|
partners List available partner APIs with pricing
|
|
54705
54771
|
partners test Test partner API endpoints (expect 402 = alive)
|
|
54706
54772
|
wallet recover Restore wallet.key from mnemonic (if generated by ClawRouter)
|
|
@@ -54735,6 +54801,8 @@ function parseArgs(args) {
|
|
|
54735
54801
|
version: false,
|
|
54736
54802
|
help: false,
|
|
54737
54803
|
doctor: false,
|
|
54804
|
+
logs: false,
|
|
54805
|
+
logsDays: 1,
|
|
54738
54806
|
partners: false,
|
|
54739
54807
|
partnersTest: false,
|
|
54740
54808
|
report: false,
|
|
@@ -54752,6 +54820,12 @@ function parseArgs(args) {
|
|
|
54752
54820
|
result.help = true;
|
|
54753
54821
|
} else if (arg === "doctor" || arg === "--doctor") {
|
|
54754
54822
|
result.doctor = true;
|
|
54823
|
+
} else if (arg === "logs") {
|
|
54824
|
+
result.logs = true;
|
|
54825
|
+
if (args[i + 1] === "--days" && args[i + 2]) {
|
|
54826
|
+
result.logsDays = parseInt(args[i + 2], 10) || 1;
|
|
54827
|
+
i += 2;
|
|
54828
|
+
}
|
|
54755
54829
|
} else if (arg === "partners") {
|
|
54756
54830
|
result.partners = true;
|
|
54757
54831
|
if (args[i + 1] === "test") {
|
|
@@ -54812,6 +54886,11 @@ async function main() {
|
|
|
54812
54886
|
await runDoctor(userQuestion, model);
|
|
54813
54887
|
process.exit(0);
|
|
54814
54888
|
}
|
|
54889
|
+
if (args.logs) {
|
|
54890
|
+
const output = await formatRecentLogs(args.logsDays);
|
|
54891
|
+
console.log(output);
|
|
54892
|
+
process.exit(0);
|
|
54893
|
+
}
|
|
54815
54894
|
if (args.partners) {
|
|
54816
54895
|
if (PARTNER_SERVICES.length === 0) {
|
|
54817
54896
|
console.log("No partner APIs available.");
|