@atbash/sdk 0.10.0-dev.0 → 0.10.0
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/LICENSE +202 -28
- package/NOTICE +10 -0
- package/README.md +96 -19
- package/THIRD-PARTY-NOTICES +10256 -0
- package/dist/browser.d.mts +846 -93
- package/dist/browser.mjs +1397 -448
- package/dist/index.d.mts +846 -93
- package/dist/index.d.ts +846 -93
- package/dist/index.js +3251 -42446
- package/dist/index.mjs +3147 -42389
- package/index.d.ts +61 -27
- package/index.js +308 -109
- package/package.json +17 -8
- package/dist/browser.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/browser.mjs
CHANGED
|
@@ -10,6 +10,9 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
10
10
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
11
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
12
|
});
|
|
13
|
+
var __esm = (fn, res) => function __init() {
|
|
14
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
15
|
+
};
|
|
13
16
|
var __commonJS = (cb, mod2) => function __require2() {
|
|
14
17
|
return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports;
|
|
15
18
|
};
|
|
@@ -30,10 +33,28 @@ var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__
|
|
|
30
33
|
mod2
|
|
31
34
|
));
|
|
32
35
|
|
|
36
|
+
// <define:__ATBASH_CHROMIA_NODE_URLS__>
|
|
37
|
+
var define_ATBASH_CHROMIA_NODE_URLS_default;
|
|
38
|
+
var init_define_ATBASH_CHROMIA_NODE_URLS = __esm({
|
|
39
|
+
"<define:__ATBASH_CHROMIA_NODE_URLS__>"() {
|
|
40
|
+
define_ATBASH_CHROMIA_NODE_URLS_default = ["https://node0.testnet.chromia.com:7740", "https://node1.testnet.chromia.com:7740"];
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// <define:__ATBASH_PRIVATE_NODE_URLS__>
|
|
45
|
+
var define_ATBASH_PRIVATE_NODE_URLS_default;
|
|
46
|
+
var init_define_ATBASH_PRIVATE_NODE_URLS = __esm({
|
|
47
|
+
"<define:__ATBASH_PRIVATE_NODE_URLS__>"() {
|
|
48
|
+
define_ATBASH_PRIVATE_NODE_URLS_default = ["https://node0-pvn-testnet.dynamic.chromia.dev:7740", "https://node1-pvn-testnet.dynamic.chromia.dev:7740", "https://node2-pvn-testnet.dynamic.chromia.dev:7740"];
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
33
52
|
// (disabled):node_modules/buffer/index.js
|
|
34
53
|
var require_buffer = __commonJS({
|
|
35
54
|
"(disabled):node_modules/buffer/index.js"() {
|
|
36
55
|
"use strict";
|
|
56
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
57
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
37
58
|
}
|
|
38
59
|
});
|
|
39
60
|
|
|
@@ -41,6 +62,8 @@ var require_buffer = __commonJS({
|
|
|
41
62
|
var require_bn = __commonJS({
|
|
42
63
|
"node_modules/bn.js/lib/bn.js"(exports, module) {
|
|
43
64
|
"use strict";
|
|
65
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
66
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44
67
|
(function(module2, exports2) {
|
|
45
68
|
"use strict";
|
|
46
69
|
function assert2(val, msg) {
|
|
@@ -2858,7 +2881,29 @@ var require_bn = __commonJS({
|
|
|
2858
2881
|
}
|
|
2859
2882
|
});
|
|
2860
2883
|
|
|
2884
|
+
// src-ts/index.ts
|
|
2885
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
2886
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
2887
|
+
|
|
2888
|
+
// src-ts/browser/native.ts
|
|
2889
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
2890
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
2891
|
+
|
|
2892
|
+
// node_modules/@noble/curves/secp256k1.js
|
|
2893
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
2894
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
2895
|
+
|
|
2896
|
+
// node_modules/@noble/hashes/sha2.js
|
|
2897
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
2898
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
2899
|
+
|
|
2900
|
+
// node_modules/@noble/hashes/_md.js
|
|
2901
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
2902
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
2903
|
+
|
|
2861
2904
|
// node_modules/@noble/hashes/utils.js
|
|
2905
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
2906
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
2862
2907
|
function isBytes(a) {
|
|
2863
2908
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
2864
2909
|
}
|
|
@@ -3279,7 +3324,13 @@ var sha256 = /* @__PURE__ */ createHasher(
|
|
|
3279
3324
|
/* @__PURE__ */ oidNist(1)
|
|
3280
3325
|
);
|
|
3281
3326
|
|
|
3327
|
+
// node_modules/@noble/curves/abstract/curve.js
|
|
3328
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
3329
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
3330
|
+
|
|
3282
3331
|
// node_modules/@noble/curves/utils.js
|
|
3332
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
3333
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
3283
3334
|
var abytes2 = (value, length, title) => abytes(value, length, title);
|
|
3284
3335
|
var anumber2 = anumber;
|
|
3285
3336
|
var bytesToHex2 = bytesToHex;
|
|
@@ -3432,6 +3483,8 @@ function validateObject(object, fields = {}, optFields = {}) {
|
|
|
3432
3483
|
}
|
|
3433
3484
|
|
|
3434
3485
|
// node_modules/@noble/curves/abstract/modular.js
|
|
3486
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
3487
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
3435
3488
|
var _0n2 = /* @__PURE__ */ BigInt(0);
|
|
3436
3489
|
var _1n2 = /* @__PURE__ */ BigInt(1);
|
|
3437
3490
|
var _2n = /* @__PURE__ */ BigInt(2);
|
|
@@ -4079,7 +4132,13 @@ function createKeygen(randomSecretKey, getPublicKey) {
|
|
|
4079
4132
|
};
|
|
4080
4133
|
}
|
|
4081
4134
|
|
|
4135
|
+
// node_modules/@noble/curves/abstract/weierstrass.js
|
|
4136
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
4137
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
4138
|
+
|
|
4082
4139
|
// node_modules/@noble/hashes/hmac.js
|
|
4140
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
4141
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
4083
4142
|
var _HMAC = class {
|
|
4084
4143
|
oHash;
|
|
4085
4144
|
iHash;
|
|
@@ -5111,6 +5170,8 @@ var Pointk1 = /* @__PURE__ */ weierstrass(secp256k1_CURVE, {
|
|
|
5111
5170
|
var secp256k1 = /* @__PURE__ */ ecdsa(Pointk1, sha256);
|
|
5112
5171
|
|
|
5113
5172
|
// node_modules/postchain-client/built/esm/index.js
|
|
5173
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
5174
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
5114
5175
|
var import_bn = __toESM(require_bn(), 1);
|
|
5115
5176
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
5116
5177
|
function getDefaultExportFromCjs(x) {
|
|
@@ -40524,7 +40585,7 @@ function requireFailoverStrategies() {
|
|
|
40524
40585
|
exports.createTimeoutPromise = createTimeoutPromise;
|
|
40525
40586
|
const utils_12 = requireUtils$1();
|
|
40526
40587
|
const httpUtil_1 = httpUtil;
|
|
40527
|
-
const
|
|
40588
|
+
const logger3 = __importStar2(logger$3);
|
|
40528
40589
|
const http_utils_1 = httpUtils;
|
|
40529
40590
|
function getUnreachableDuration(statusCode, error4) {
|
|
40530
40591
|
if ((0, http_utils_1.isNetworkError)(error4)) {
|
|
@@ -40625,7 +40686,7 @@ function requireFailoverStrategies() {
|
|
|
40625
40686
|
while (true) {
|
|
40626
40687
|
if (groupedSuccessfulResponses.maxNumberOfEqualResponses() >= bftMajorityThreshold) {
|
|
40627
40688
|
if (groupedSuccessfulResponses.numberOfDistinctResponses() > 1) {
|
|
40628
|
-
|
|
40689
|
+
logger3.warning(`Got disagreeing responses, but could still reach BFT majority`);
|
|
40629
40690
|
}
|
|
40630
40691
|
return groupedSuccessfulResponses.majorityResponse();
|
|
40631
40692
|
}
|
|
@@ -40663,7 +40724,7 @@ function requireFailoverStrategies() {
|
|
|
40663
40724
|
if (!isError4 && !error4) {
|
|
40664
40725
|
return { error: error4, statusCode, rspBody, transactionTimestamp };
|
|
40665
40726
|
}
|
|
40666
|
-
|
|
40727
|
+
logger3.info(`${method} request failed on ${endpoint.url}. Attempt: ${attempt + 1} / ${config2.attemptsPerEndpoint}`);
|
|
40667
40728
|
yield (0, utils_12.sleep)(config2.attemptInterval);
|
|
40668
40729
|
}
|
|
40669
40730
|
return { error: error4, statusCode, rspBody, transactionTimestamp };
|
|
@@ -40699,7 +40760,7 @@ function requireFailoverStrategies() {
|
|
|
40699
40760
|
if (isServerError) {
|
|
40700
40761
|
const duration = getUnreachableDuration(statusCode !== null && statusCode !== void 0 ? statusCode : void 0, response.error);
|
|
40701
40762
|
nodeManager2.makeNodeUnavailable(node2.url, duration);
|
|
40702
|
-
|
|
40763
|
+
logger3.info(`request failed with server error on ${node2.url} trying next node`);
|
|
40703
40764
|
break;
|
|
40704
40765
|
}
|
|
40705
40766
|
if (isClientError) {
|
|
@@ -40707,11 +40768,11 @@ function requireFailoverStrategies() {
|
|
|
40707
40768
|
return { error: error4, statusCode, rspBody, transactionTimestamp };
|
|
40708
40769
|
}
|
|
40709
40770
|
if (!nodeManager2.useStickyNode) {
|
|
40710
|
-
|
|
40771
|
+
logger3.info(`request failed client error on ${node2.url} trying next node`);
|
|
40711
40772
|
break;
|
|
40712
40773
|
}
|
|
40713
40774
|
}
|
|
40714
|
-
|
|
40775
|
+
logger3.info(`${method} request failed on ${node2.url}. Attempt: ${attempt + 1} / ${config2.attemptsPerEndpoint}`);
|
|
40715
40776
|
if (config2.attemptInterval > 0) {
|
|
40716
40777
|
yield (0, utils_12.sleep)(config2.attemptInterval);
|
|
40717
40778
|
}
|
|
@@ -40940,7 +41001,7 @@ function requireUtils$1() {
|
|
|
40940
41001
|
exports.getBlockchainRidFromIid = getBlockchainRidFromIid;
|
|
40941
41002
|
exports.convertToPrintable = convertToPrintable;
|
|
40942
41003
|
const buffer_12 = buffer$3;
|
|
40943
|
-
const
|
|
41004
|
+
const logger3 = __importStar2(logger$3);
|
|
40944
41005
|
const errors_12 = errors;
|
|
40945
41006
|
const gtxTool = __importStar2(gtx$1);
|
|
40946
41007
|
const errors_2 = errors;
|
|
@@ -41023,7 +41084,7 @@ function requireUtils$1() {
|
|
|
41023
41084
|
function validTxRid(txRID) {
|
|
41024
41085
|
if (txRID.length != 32) {
|
|
41025
41086
|
const error4 = new errors_12.InvalidTxRidException(txRID);
|
|
41026
|
-
|
|
41087
|
+
logger3.error(error4.toString());
|
|
41027
41088
|
return false;
|
|
41028
41089
|
}
|
|
41029
41090
|
return true;
|
|
@@ -41426,7 +41487,7 @@ function requireUtils$1() {
|
|
|
41426
41487
|
function handleGetResponse(error4, statusCode, responseObject, callback) {
|
|
41427
41488
|
try {
|
|
41428
41489
|
const responseObjectPrintable = convertToPrintable(responseObject);
|
|
41429
|
-
|
|
41490
|
+
logger3.debug(`error: ${error4}, status code: ${statusCode}, response body: ${responseObjectPrintable}`);
|
|
41430
41491
|
if (error4) {
|
|
41431
41492
|
return callback(error4, null);
|
|
41432
41493
|
}
|
|
@@ -41436,16 +41497,16 @@ function requireUtils$1() {
|
|
|
41436
41497
|
return callback(null, responseObject);
|
|
41437
41498
|
} catch (error5) {
|
|
41438
41499
|
callback(error5, null);
|
|
41439
|
-
|
|
41500
|
+
logger3.error(`client.handleGetResponse(): Failed to call the callback function. ${error5}`);
|
|
41440
41501
|
}
|
|
41441
41502
|
}
|
|
41442
41503
|
function handlePostResponse(error4, statusCode, responseObject, callback) {
|
|
41443
41504
|
var _a2;
|
|
41444
41505
|
const responseObjectPrintable = convertToPrintable(responseObject);
|
|
41445
|
-
|
|
41506
|
+
logger3.debug(`error: ${error4}, status code: ${statusCode}, response body: ${responseObjectPrintable}`);
|
|
41446
41507
|
try {
|
|
41447
41508
|
if (error4) {
|
|
41448
|
-
|
|
41509
|
+
logger3.error(`In client post(). ${error4}`);
|
|
41449
41510
|
callback(error4, null);
|
|
41450
41511
|
} else if (!statusCode || !(0, http_utils_1.isSuccessfulStatusCode)(statusCode)) {
|
|
41451
41512
|
let errorMessage2 = `Unexpected status code from server. Code: ${statusCode}.`;
|
|
@@ -41453,14 +41514,14 @@ function requireUtils$1() {
|
|
|
41453
41514
|
if (responseObjectPrintable) {
|
|
41454
41515
|
errorMessage2 += ` Message: ${responseObjectPrintable}.`;
|
|
41455
41516
|
}
|
|
41456
|
-
|
|
41517
|
+
logger3.error(errorMessage2);
|
|
41457
41518
|
callback(new errors_12.UnexpectedStatusError(statusCode !== null && statusCode !== void 0 ? statusCode : 400, errorMessageInResponseBody || responseObjectPrintable), responseObject);
|
|
41458
41519
|
} else {
|
|
41459
|
-
|
|
41520
|
+
logger3.info(`Calling responseCallback with responseObject: ${responseObjectPrintable}`);
|
|
41460
41521
|
callback(null, responseObject);
|
|
41461
41522
|
}
|
|
41462
41523
|
} catch (error5) {
|
|
41463
|
-
|
|
41524
|
+
logger3.error(`client.handlePostResponse(): Failed to call callback function ${error5}`);
|
|
41464
41525
|
}
|
|
41465
41526
|
}
|
|
41466
41527
|
function getBlockchainRidFromIid(_a2) {
|
|
@@ -42198,7 +42259,7 @@ function requireBlockchainClient() {
|
|
|
42198
42259
|
const crypto_12 = requireCryptoBrowserify();
|
|
42199
42260
|
const cloneDeep_1$1 = __importDefault2(cloneDeep_1);
|
|
42200
42261
|
const IccfProofTxMaterialBuilder_1 = requireIccfProofTxMaterialBuilder();
|
|
42201
|
-
const
|
|
42262
|
+
const logger3 = __importStar2(logger$3);
|
|
42202
42263
|
const formatter_12 = formatter;
|
|
42203
42264
|
const serialization_12 = serialization$2;
|
|
42204
42265
|
const gtxTool = __importStar2(gtx$1);
|
|
@@ -42240,7 +42301,7 @@ function requireBlockchainClient() {
|
|
|
42240
42301
|
},
|
|
42241
42302
|
signTransaction(transaction, signMethod2, callback) {
|
|
42242
42303
|
return __awaiter2(this, void 0, void 0, function* () {
|
|
42243
|
-
|
|
42304
|
+
logger3.debug(`Signing transaction with ${!(0, utils_12.isKeyPair)(signMethod2) ? "signature provider containing " : ""}pubKey: ${(0, formatter_12.toString)(signMethod2.pubKey)}`);
|
|
42244
42305
|
const gtx2 = (0, utils_12.getGTXFromBufferOrTransactionOrOperation)(transaction, config2.blockchainRid);
|
|
42245
42306
|
try {
|
|
42246
42307
|
const signedTx = yield (0, utils_12.isKeyPair)(signMethod2) ? gtxTool.sign(gtx2, signMethod2.privKey, config2.merkleHashVersion, signMethod2.pubKey) : gtxTool.sign(gtx2, signMethod2, config2.merkleHashVersion);
|
|
@@ -42265,7 +42326,7 @@ function requireBlockchainClient() {
|
|
|
42265
42326
|
const promiEvent = new promiEvents_12.Web3PromiEvent((resolve2, reject) => __awaiter2(this, void 0, void 0, function* () {
|
|
42266
42327
|
let error4 = null;
|
|
42267
42328
|
for (let i = 0; i < config2.retryTransactionPolling.count; i++) {
|
|
42268
|
-
|
|
42329
|
+
logger3.info(`sendTransactionWithRetries attempt ${i + 1} of ${config2.retryTransactionPolling.count}`);
|
|
42269
42330
|
const tmpPromiEvent = sendOnce().on(enums_12.TransactionEvent.ClusterAnchoringConfirmation, (receipt) => {
|
|
42270
42331
|
promiEvent.emit(enums_12.TransactionEvent.ClusterAnchoringConfirmation, receipt);
|
|
42271
42332
|
}).on(enums_12.TransactionEvent.SystemAnchoringConfirmation, (receipt) => {
|
|
@@ -42277,7 +42338,7 @@ function requireBlockchainClient() {
|
|
|
42277
42338
|
}).on(enums_12.TransactionEvent.DappConfirmed, (receipt) => {
|
|
42278
42339
|
promiEvent.emit(enums_12.TransactionEvent.DappConfirmed, receipt);
|
|
42279
42340
|
}).catch((tmpError) => {
|
|
42280
|
-
|
|
42341
|
+
logger3.warning(`sendTransactionWithRetries error on attempt ${i + 1} of ${config2.retryTransactionPolling.count}: ${tmpError}`);
|
|
42281
42342
|
promiEvent.emit(enums_12.TransactionEvent.Rejected, tmpError);
|
|
42282
42343
|
error4 = tmpError;
|
|
42283
42344
|
});
|
|
@@ -43012,11 +43073,11 @@ function requireDecodeTransactionToGtx() {
|
|
|
43012
43073
|
Object.defineProperty(decodeTransactionToGtx, "__esModule", { value: true });
|
|
43013
43074
|
decodeTransactionToGtx.decodeTransactionToGtx = decodeTransactionToGtx$1;
|
|
43014
43075
|
const gtxTool = __importStar2(gtx$1);
|
|
43015
|
-
const
|
|
43076
|
+
const logger3 = __importStar2(logger$3);
|
|
43016
43077
|
const dump_1 = requireDump();
|
|
43017
43078
|
function decodeTransactionToGtx$1(encodedTransaction) {
|
|
43018
43079
|
const gtx2 = gtxTool.deserialize(encodedTransaction);
|
|
43019
|
-
|
|
43080
|
+
logger3.debug(`Output from deserializing a raw transaction: ${(0, dump_1.dumpGtv)(gtx2)}`);
|
|
43020
43081
|
return gtx2;
|
|
43021
43082
|
}
|
|
43022
43083
|
return decodeTransactionToGtx;
|
|
@@ -43233,17 +43294,11 @@ var index = /* @__PURE__ */ getDefaultExportFromCjs(builtExports);
|
|
|
43233
43294
|
|
|
43234
43295
|
// src-ts/browser/native.ts
|
|
43235
43296
|
var { Buffer: Buffer3, gtx: pcgtx } = index;
|
|
43236
|
-
var
|
|
43237
|
-
var
|
|
43238
|
-
var
|
|
43239
|
-
var DEFAULT_CHROMIA_NODE_URLS_ARR =
|
|
43240
|
-
|
|
43241
|
-
"https://node1.testnet.chromia.com:7740",
|
|
43242
|
-
"https://node3.testnet.chromia.com:7740"
|
|
43243
|
-
];
|
|
43244
|
-
var DEFAULT_PRIVATE_NODE_URLS_ARR = [
|
|
43245
|
-
"https://node0-pvn-testnet.dynamic.chromia.dev"
|
|
43246
|
-
];
|
|
43297
|
+
var ATBASH_ENDPOINT = "https://atbash.ai";
|
|
43298
|
+
var ATBASH_BLOCKCHAIN_RID = "0163241D9AF137638E63E48EFCDE15510F38C2426F7AD5DC726AF60351BF4DFE";
|
|
43299
|
+
var ATBASH_PRIVATE_BLOCKCHAIN_RID = "39FFD3557D0296CB2C57FDC6A3B8C024E95639CF4964DA08141AC20C6344D408";
|
|
43300
|
+
var DEFAULT_CHROMIA_NODE_URLS_ARR = define_ATBASH_CHROMIA_NODE_URLS_default;
|
|
43301
|
+
var DEFAULT_PRIVATE_NODE_URLS_ARR = define_ATBASH_PRIVATE_NODE_URLS_default;
|
|
43247
43302
|
var MERKLE_HASH_VERSION = 2;
|
|
43248
43303
|
function stripHex(s2) {
|
|
43249
43304
|
return s2.trim().replace(/^0x/i, "").toLowerCase();
|
|
@@ -43394,15 +43449,23 @@ var native = {
|
|
|
43394
43449
|
deriveMemoryKey,
|
|
43395
43450
|
encryptMemoryContent,
|
|
43396
43451
|
decryptMemoryContent,
|
|
43397
|
-
DEFAULT_BLOCKCHAIN_RID:
|
|
43398
|
-
DEFAULT_PRIVATE_BLOCKCHAIN_RID:
|
|
43399
|
-
DEFAULT_ENDPOINT:
|
|
43400
|
-
// Browser has no NAPI channel to Rust's HONEYCOMB_KEY — telemetry
|
|
43401
|
-
// silently no-ops. `HONEYCOMB_API_KEY` env var still overrides at runtime.
|
|
43402
|
-
HONEYCOMB_KEY: "",
|
|
43452
|
+
DEFAULT_BLOCKCHAIN_RID: ATBASH_BLOCKCHAIN_RID,
|
|
43453
|
+
DEFAULT_PRIVATE_BLOCKCHAIN_RID: ATBASH_PRIVATE_BLOCKCHAIN_RID,
|
|
43454
|
+
DEFAULT_ENDPOINT: ATBASH_ENDPOINT,
|
|
43403
43455
|
defaultChromiaNodeUrls: () => [...DEFAULT_CHROMIA_NODE_URLS_ARR],
|
|
43404
43456
|
defaultPrivateNodeUrls: () => [...DEFAULT_PRIVATE_NODE_URLS_ARR],
|
|
43405
43457
|
// Server-only surfaces — throw at runtime, keep types satisfied.
|
|
43458
|
+
// The memory signers are here and not with the other signing shims because
|
|
43459
|
+
// their args are encrypted by `encryptMemoryContent`, which this build does
|
|
43460
|
+
// not have: a browser could sign the transaction but never produce one worth
|
|
43461
|
+
// sending.
|
|
43462
|
+
signAddAgentMemory: stub("signAddAgentMemory"),
|
|
43463
|
+
signRollbackAgentMemory: stub("signRollbackAgentMemory"),
|
|
43464
|
+
extractMemoryEdits: stub("extractMemoryEdits"),
|
|
43465
|
+
applyMemoryEdits: stub("applyMemoryEdits"),
|
|
43466
|
+
memorySlotForPath: stub("memorySlotForPath"),
|
|
43467
|
+
isSafeMemorySlot: stub("isSafeMemorySlot"),
|
|
43468
|
+
defaultAgentHomeDirs: stub("defaultAgentHomeDirs"),
|
|
43406
43469
|
classifyMemoryWrite: stub("classifyMemoryWrite"),
|
|
43407
43470
|
classifyMemoryRead: stub("classifyMemoryRead"),
|
|
43408
43471
|
defaultMemoryWriteToolNames: stub("defaultMemoryWriteToolNames"),
|
|
@@ -43426,9 +43489,10 @@ var native = {
|
|
|
43426
43489
|
validateMemoryId: stub("validateMemoryId"),
|
|
43427
43490
|
validateRollbackReason: stub("validateRollbackReason"),
|
|
43428
43491
|
validateMemoryNonce: stub("validateMemoryNonce"),
|
|
43492
|
+
validateFilePath: stub("validateFilePath"),
|
|
43429
43493
|
buildGetActiveMemoryIdQuery: stub("buildGetActiveMemoryIdQuery"),
|
|
43430
|
-
|
|
43431
|
-
|
|
43494
|
+
buildGetRecentAgentMemoryQuery: stub("buildGetRecentAgentMemoryQuery"),
|
|
43495
|
+
buildGetActiveAgentMemoryQuery: stub("buildGetActiveAgentMemoryQuery"),
|
|
43432
43496
|
buildGetAgentMemoryHistoryQuery: stub("buildGetAgentMemoryHistoryQuery"),
|
|
43433
43497
|
buildGetAgentMemoryRollbackHistoryQuery: stub("buildGetAgentMemoryRollbackHistoryQuery"),
|
|
43434
43498
|
buildGetAgentMemoryByIdQuery: stub("buildGetAgentMemoryByIdQuery"),
|
|
@@ -43447,16 +43511,23 @@ var native = {
|
|
|
43447
43511
|
OP_ROLLBACK_AGENT_MEMORY: "rollback_agent_memory",
|
|
43448
43512
|
OP_LOG_ENCRYPTED_TOOL_CALL: "log_encrypted_tool_call",
|
|
43449
43513
|
QUERY_GET_ACTIVE_MEMORY_ID: "get_active_memory_id",
|
|
43450
|
-
|
|
43451
|
-
|
|
43514
|
+
QUERY_GET_RECENT_AGENT_MEMORY: "get_recent_agent_memory",
|
|
43515
|
+
QUERY_GET_ACTIVE_AGENT_MEMORY: "get_active_agent_memory",
|
|
43452
43516
|
QUERY_GET_AGENT_MEMORY_HISTORY: "get_agent_memory_history",
|
|
43453
43517
|
QUERY_GET_AGENT_MEMORY_BY_ID: "get_agent_memory_by_id",
|
|
43454
43518
|
QUERY_GET_AGENT_MEMORY_ROLLBACK_HISTORY: "get_agent_memory_rollback_history",
|
|
43455
43519
|
ARG_AGENT_PUBKEY: "agent_pubkey",
|
|
43456
|
-
ARG_ID: "id"
|
|
43520
|
+
ARG_ID: "id",
|
|
43521
|
+
ARG_FILE_PATH: "file_path"
|
|
43457
43522
|
};
|
|
43458
43523
|
|
|
43524
|
+
// src-ts/client.ts
|
|
43525
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
43526
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
43527
|
+
|
|
43459
43528
|
// src-ts/random.ts
|
|
43529
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
43530
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
43460
43531
|
function randomBytes4(size) {
|
|
43461
43532
|
const buf = new Uint8Array(size);
|
|
43462
43533
|
globalThis.crypto.getRandomValues(buf);
|
|
@@ -43471,7 +43542,39 @@ function randomHex(size) {
|
|
|
43471
43542
|
return hex;
|
|
43472
43543
|
}
|
|
43473
43544
|
|
|
43545
|
+
// src-ts/auth-bearer.ts
|
|
43546
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
43547
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
43548
|
+
var BEARER_TTL_MS = 4 * 60 * 1e3;
|
|
43549
|
+
var bearers = /* @__PURE__ */ new Map();
|
|
43550
|
+
function agentAuthBearer(auth, blockchainRid) {
|
|
43551
|
+
const key3 = `${auth.pubkey}:${blockchainRid}`;
|
|
43552
|
+
const now = Date.now();
|
|
43553
|
+
const cached = bearers.get(key3);
|
|
43554
|
+
if (cached && now - cached.issuedAt < BEARER_TTL_MS) return cached.hex;
|
|
43555
|
+
const hex = native.signLogToolCall(
|
|
43556
|
+
`auth-${now.toString(36)}-${randomHex(4)}`,
|
|
43557
|
+
`auth:${now}`,
|
|
43558
|
+
"",
|
|
43559
|
+
"auth-bearer",
|
|
43560
|
+
"",
|
|
43561
|
+
auth.privkey,
|
|
43562
|
+
blockchainRid
|
|
43563
|
+
);
|
|
43564
|
+
bearers.set(key3, { hex, issuedAt: now });
|
|
43565
|
+
return hex;
|
|
43566
|
+
}
|
|
43567
|
+
function agentAuthHeaders(auth, blockchainRid) {
|
|
43568
|
+
return { Authorization: `Bearer ${agentAuthBearer(auth, blockchainRid)}` };
|
|
43569
|
+
}
|
|
43570
|
+
|
|
43571
|
+
// src-ts/chain-config.ts
|
|
43572
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
43573
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
43574
|
+
|
|
43474
43575
|
// src-ts/constants.ts
|
|
43576
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
43577
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
43475
43578
|
var DEFAULT_ENDPOINT = native.DEFAULT_ENDPOINT;
|
|
43476
43579
|
var DEFAULT_CHROMIA_NODE_URLS = Object.freeze(
|
|
43477
43580
|
native.defaultChromiaNodeUrls()
|
|
@@ -43493,8 +43596,21 @@ var PRIVATE_CHAIN = {
|
|
|
43493
43596
|
blockchainRid: DEFAULT_PRIVATE_BLOCKCHAIN_RID,
|
|
43494
43597
|
nodeUrls: DEFAULT_PRIVATE_NODE_URLS
|
|
43495
43598
|
};
|
|
43599
|
+
function chainForNetwork(network) {
|
|
43600
|
+
return network === "private" ? PRIVATE_CHAIN : PUBLIC_CHAIN;
|
|
43601
|
+
}
|
|
43602
|
+
|
|
43603
|
+
// src-ts/browser/encrypted-toolcall.ts
|
|
43604
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
43605
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
43606
|
+
|
|
43607
|
+
// src-ts/browser/crypto-ecies.ts
|
|
43608
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
43609
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
43496
43610
|
|
|
43497
43611
|
// node_modules/@noble/hashes/hkdf.js
|
|
43612
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
43613
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
43498
43614
|
function extract(hash3, ikm, salt) {
|
|
43499
43615
|
ahash(hash3);
|
|
43500
43616
|
if (salt === void 0)
|
|
@@ -43534,7 +43650,17 @@ function expand2(hash3, prk, info2, length = 32) {
|
|
|
43534
43650
|
}
|
|
43535
43651
|
var hkdf = (hash3, ikm, salt, info2, length) => expand2(hash3, extract(hash3, ikm, salt), info2, length);
|
|
43536
43652
|
|
|
43653
|
+
// node_modules/@noble/ciphers/aes.js
|
|
43654
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
43655
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
43656
|
+
|
|
43657
|
+
// node_modules/@noble/ciphers/_polyval.js
|
|
43658
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
43659
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
43660
|
+
|
|
43537
43661
|
// node_modules/@noble/ciphers/utils.js
|
|
43662
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
43663
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
43538
43664
|
function isBytes3(a) {
|
|
43539
43665
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
43540
43666
|
}
|
|
@@ -44126,6 +44252,46 @@ function encryptedLength(plaintextByteLength) {
|
|
|
44126
44252
|
return HEADER_LEN + plaintextByteLength + GCM_TAG_LEN;
|
|
44127
44253
|
}
|
|
44128
44254
|
|
|
44255
|
+
// src-ts/crypto/envelope.ts
|
|
44256
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44257
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44258
|
+
var PREFIX = "atb1";
|
|
44259
|
+
var SEPARATOR = ".";
|
|
44260
|
+
function toBase64(bytes) {
|
|
44261
|
+
let binary = "";
|
|
44262
|
+
for (const b of bytes) binary += String.fromCharCode(b);
|
|
44263
|
+
return btoa(binary);
|
|
44264
|
+
}
|
|
44265
|
+
function fromBase64(text) {
|
|
44266
|
+
const binary = atob(text);
|
|
44267
|
+
const out = new Uint8Array(binary.length);
|
|
44268
|
+
for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i);
|
|
44269
|
+
return out;
|
|
44270
|
+
}
|
|
44271
|
+
function packEnvelope(payload, keyFingerprint = "", claimHash = "") {
|
|
44272
|
+
return [PREFIX, keyFingerprint, claimHash, toBase64(payload)].join(SEPARATOR);
|
|
44273
|
+
}
|
|
44274
|
+
function fieldWidthOk(value, hexChars) {
|
|
44275
|
+
return value.length === 0 ? true : value.length === hexChars && /^[0-9a-f]+$/.test(value);
|
|
44276
|
+
}
|
|
44277
|
+
function isEnvelope(value) {
|
|
44278
|
+
if (typeof value !== "string" || !value.startsWith(PREFIX + SEPARATOR)) return false;
|
|
44279
|
+
const parts = value.split(SEPARATOR);
|
|
44280
|
+
return parts.length >= 4 && fieldWidthOk(parts[1], 16) && fieldWidthOk(parts[2], 64);
|
|
44281
|
+
}
|
|
44282
|
+
function parseEnvelope(value) {
|
|
44283
|
+
if (!isEnvelope(value)) return null;
|
|
44284
|
+
const [, keyFingerprint, claimHash, ...rest] = value.split(SEPARATOR);
|
|
44285
|
+
try {
|
|
44286
|
+
return { keyFingerprint, claimHash, payload: fromBase64(rest.join(SEPARATOR)) };
|
|
44287
|
+
} catch {
|
|
44288
|
+
return null;
|
|
44289
|
+
}
|
|
44290
|
+
}
|
|
44291
|
+
function keyFingerprintOf(pubKeyHex) {
|
|
44292
|
+
return pubKeyHex.trim().replace(/^0x/i, "").toLowerCase().slice(0, 16);
|
|
44293
|
+
}
|
|
44294
|
+
|
|
44129
44295
|
// src-ts/browser/encrypted-toolcall.ts
|
|
44130
44296
|
var { Buffer: PolyBuffer, gtx: pcgtx2 } = index;
|
|
44131
44297
|
var MERKLE_HASH_VERSION2 = 2;
|
|
@@ -44138,6 +44304,9 @@ function claimHashHex(toolName, action, context, toolArgsJson) {
|
|
|
44138
44304
|
]);
|
|
44139
44305
|
return bytesToHex2(sha256(new TextEncoder().encode(canonical)));
|
|
44140
44306
|
}
|
|
44307
|
+
function columnAad(toolCallId, column) {
|
|
44308
|
+
return `${toolCallId}:${column}`;
|
|
44309
|
+
}
|
|
44141
44310
|
function normalizeActionForHash(action) {
|
|
44142
44311
|
action = action.trim();
|
|
44143
44312
|
try {
|
|
@@ -44183,31 +44352,34 @@ function signOpWithBytes(opName, args, privkeyHex, blockchainRidHex) {
|
|
|
44183
44352
|
return pcgtx2.serialize(g).toString("hex");
|
|
44184
44353
|
}
|
|
44185
44354
|
function signEncryptedToolCall(toolCallId, action, context, toolName, toolArgsJson, orgEncryptionPubKey, privkeyHex, blockchainRidHex) {
|
|
44186
|
-
const
|
|
44187
|
-
|
|
44188
|
-
|
|
44189
|
-
|
|
44190
|
-
|
|
44191
|
-
|
|
44192
|
-
|
|
44193
|
-
|
|
44194
|
-
|
|
44195
|
-
toolCallId,
|
|
44196
|
-
EciesDomain.toolCall
|
|
44355
|
+
const fingerprint = keyFingerprintOf(orgEncryptionPubKey);
|
|
44356
|
+
const seal = (text, column) => text === "" ? "" : packEnvelope(
|
|
44357
|
+
encryptForOrg(
|
|
44358
|
+
text,
|
|
44359
|
+
orgEncryptionPubKey,
|
|
44360
|
+
columnAad(toolCallId, column),
|
|
44361
|
+
EciesDomain.toolCall
|
|
44362
|
+
),
|
|
44363
|
+
fingerprint
|
|
44197
44364
|
);
|
|
44198
|
-
const
|
|
44199
|
-
|
|
44365
|
+
const actionColumn = packEnvelope(
|
|
44366
|
+
encryptForOrg(
|
|
44367
|
+
action,
|
|
44368
|
+
orgEncryptionPubKey,
|
|
44369
|
+
columnAad(toolCallId, "action"),
|
|
44370
|
+
EciesDomain.toolCall
|
|
44371
|
+
),
|
|
44372
|
+
fingerprint,
|
|
44373
|
+
claimHashHex(toolName, action, context, toolArgsJson)
|
|
44200
44374
|
);
|
|
44201
44375
|
return signOpWithBytes(
|
|
44202
|
-
"
|
|
44376
|
+
"log_tool_call",
|
|
44203
44377
|
[
|
|
44204
44378
|
toolCallId,
|
|
44379
|
+
actionColumn,
|
|
44380
|
+
seal(context, "context"),
|
|
44205
44381
|
toolName,
|
|
44206
|
-
|
|
44207
|
-
actionHash,
|
|
44208
|
-
// Empty = "org's current key"; chain resolves it.
|
|
44209
|
-
PolyBuffer.from(new Uint8Array(0)),
|
|
44210
|
-
claimHashHex(toolName, action, context, toolArgsJson)
|
|
44382
|
+
seal(toolArgsJson, "tool_args")
|
|
44211
44383
|
],
|
|
44212
44384
|
privkeyHex,
|
|
44213
44385
|
blockchainRidHex
|
|
@@ -44215,11 +44387,23 @@ function signEncryptedToolCall(toolCallId, action, context, toolName, toolArgsJs
|
|
|
44215
44387
|
}
|
|
44216
44388
|
|
|
44217
44389
|
// src-ts/endpoint.ts
|
|
44218
|
-
|
|
44219
|
-
|
|
44220
|
-
|
|
44221
|
-
|
|
44222
|
-
|
|
44390
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44391
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44392
|
+
function buildAllowedJudgeHosts() {
|
|
44393
|
+
return /* @__PURE__ */ new Set([
|
|
44394
|
+
"atbash.ai",
|
|
44395
|
+
"www.atbash.ai",
|
|
44396
|
+
new URL(DEFAULT_ENDPOINT).hostname.toLowerCase()
|
|
44397
|
+
]);
|
|
44398
|
+
}
|
|
44399
|
+
var ALLOWED_JUDGE_HOSTS = buildAllowedJudgeHosts();
|
|
44400
|
+
function isAllowlistedJudgeHost(endpoint) {
|
|
44401
|
+
try {
|
|
44402
|
+
return ALLOWED_JUDGE_HOSTS.has(new URL(endpoint).hostname.toLowerCase());
|
|
44403
|
+
} catch {
|
|
44404
|
+
return false;
|
|
44405
|
+
}
|
|
44406
|
+
}
|
|
44223
44407
|
function validateJudgeEndpoint(judge) {
|
|
44224
44408
|
const policy = judge?.policy === "self-hosted" ? "self-hosted" : "default";
|
|
44225
44409
|
const candidate = judge?.endpoint?.trim() || DEFAULT_ENDPOINT;
|
|
@@ -44262,16 +44446,30 @@ function validateJudgeEndpoint(judge) {
|
|
|
44262
44446
|
}
|
|
44263
44447
|
|
|
44264
44448
|
// src-ts/errors.ts
|
|
44449
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44450
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44265
44451
|
var AtbashAPIError = class extends Error {
|
|
44266
44452
|
/** HTTP status code (or 0 if the request never completed). */
|
|
44267
44453
|
status;
|
|
44268
44454
|
/** Raw response body text (may be empty). */
|
|
44269
44455
|
body;
|
|
44270
|
-
|
|
44271
|
-
|
|
44456
|
+
/**
|
|
44457
|
+
* Request path this status came from, e.g. `/api/v1/judge` — absent when the
|
|
44458
|
+
* request never reached a response (transport failures carry status 0).
|
|
44459
|
+
*
|
|
44460
|
+
* A status alone does not say what failed. Several routes answer one call, and
|
|
44461
|
+
* more than one of them can 404: a caller reading only `404` cannot tell "this
|
|
44462
|
+
* agent is not registered" from "the chain-routing lookup did not resolve", and
|
|
44463
|
+
* has to guess from the body's prose — which a 404 raised before any handler
|
|
44464
|
+
* ran does not carry. The path is the fact that settles it.
|
|
44465
|
+
*/
|
|
44466
|
+
path;
|
|
44467
|
+
constructor(status, body, statusText = "", endpoint = DEFAULT_ENDPOINT, path3) {
|
|
44468
|
+
super(enrich(status, body, statusText, endpoint, path3));
|
|
44272
44469
|
this.name = "AtbashAPIError";
|
|
44273
44470
|
this.status = status;
|
|
44274
44471
|
this.body = body;
|
|
44472
|
+
this.path = path3;
|
|
44275
44473
|
}
|
|
44276
44474
|
};
|
|
44277
44475
|
var SignatureVerificationError = class extends Error {
|
|
@@ -44280,9 +44478,9 @@ var SignatureVerificationError = class extends Error {
|
|
|
44280
44478
|
this.name = "SignatureVerificationError";
|
|
44281
44479
|
}
|
|
44282
44480
|
};
|
|
44283
|
-
function enrich(status, body, statusText, endpoint) {
|
|
44481
|
+
function enrich(status, body, statusText, endpoint, path3) {
|
|
44284
44482
|
const dashboard = endpoint.replace(/\/+$/, "") || DEFAULT_ENDPOINT;
|
|
44285
|
-
let msg = `API error ${status}: ${body || statusText}`;
|
|
44483
|
+
let msg = `API error ${status}${path3 ? ` from ${path3}` : ""}: ${body || statusText}`;
|
|
44286
44484
|
const lowered = body.toLowerCase();
|
|
44287
44485
|
if (lowered.includes("agent not registered")) {
|
|
44288
44486
|
msg += `
|
|
@@ -44304,6 +44502,8 @@ function enrich(status, body, statusText, endpoint) {
|
|
|
44304
44502
|
}
|
|
44305
44503
|
|
|
44306
44504
|
// src-ts/http/client.ts
|
|
44505
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44506
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44307
44507
|
var HttpClient = class {
|
|
44308
44508
|
baseUrl;
|
|
44309
44509
|
timeoutMs;
|
|
@@ -44336,11 +44536,80 @@ var HttpClient = class {
|
|
|
44336
44536
|
});
|
|
44337
44537
|
}
|
|
44338
44538
|
async fetch(url, init4) {
|
|
44339
|
-
|
|
44539
|
+
try {
|
|
44540
|
+
return await fetch(url, {
|
|
44541
|
+
...init4,
|
|
44542
|
+
signal: AbortSignal.timeout(this.timeoutMs)
|
|
44543
|
+
});
|
|
44544
|
+
} catch (err) {
|
|
44545
|
+
throw classifyTransportError(err, url, init4.method ?? "GET", this.timeoutMs);
|
|
44546
|
+
}
|
|
44547
|
+
}
|
|
44548
|
+
};
|
|
44549
|
+
var HttpTransportError = class extends Error {
|
|
44550
|
+
kind;
|
|
44551
|
+
constructor(kind, message, options) {
|
|
44552
|
+
super(message, options);
|
|
44553
|
+
this.name = "HttpTransportError";
|
|
44554
|
+
this.kind = kind;
|
|
44340
44555
|
}
|
|
44341
44556
|
};
|
|
44557
|
+
function classifyTransportError(err, url, method, timeoutMs) {
|
|
44558
|
+
const name2 = err instanceof Error ? err.name : "";
|
|
44559
|
+
const cause = err instanceof Error ? err.cause : void 0;
|
|
44560
|
+
const code2 = cause && typeof cause === "object" && "code" in cause ? String(cause.code) : "";
|
|
44561
|
+
if (name2 === "TimeoutError") {
|
|
44562
|
+
return new HttpTransportError(
|
|
44563
|
+
"timeout",
|
|
44564
|
+
`${method} ${url} did not respond within ${timeoutMs} ms \u2014 the judge may be slow to boot or the LLM is under load; retry in a moment`,
|
|
44565
|
+
{ cause: err }
|
|
44566
|
+
);
|
|
44567
|
+
}
|
|
44568
|
+
if (name2 === "AbortError") {
|
|
44569
|
+
return new HttpTransportError(
|
|
44570
|
+
"aborted",
|
|
44571
|
+
`${method} ${url} was cancelled by the caller`,
|
|
44572
|
+
{ cause: err }
|
|
44573
|
+
);
|
|
44574
|
+
}
|
|
44575
|
+
if (code2 === "UND_ERR_CONNECT_TIMEOUT") {
|
|
44576
|
+
return new HttpTransportError(
|
|
44577
|
+
"timeout",
|
|
44578
|
+
`${method} ${url} could not establish a connection before the transport deadline \u2014 check the endpoint and network`,
|
|
44579
|
+
{ cause: err }
|
|
44580
|
+
);
|
|
44581
|
+
}
|
|
44582
|
+
if (code2 === "ENOTFOUND" || code2 === "EAI_AGAIN") {
|
|
44583
|
+
return new HttpTransportError(
|
|
44584
|
+
"dns",
|
|
44585
|
+
`could not resolve the judge hostname (${url}) \u2014 check the endpoint and DNS`,
|
|
44586
|
+
{ cause: err }
|
|
44587
|
+
);
|
|
44588
|
+
}
|
|
44589
|
+
if (code2 === "ECONNREFUSED") {
|
|
44590
|
+
return new HttpTransportError(
|
|
44591
|
+
"connect_refused",
|
|
44592
|
+
`judge refused the connection (${url}) \u2014 the service may be down or restarting`,
|
|
44593
|
+
{ cause: err }
|
|
44594
|
+
);
|
|
44595
|
+
}
|
|
44596
|
+
if (code2 === "ECONNRESET" || code2 === "EPIPE") {
|
|
44597
|
+
return new HttpTransportError(
|
|
44598
|
+
"connection_reset",
|
|
44599
|
+
`judge dropped the connection mid-request (${url}) \u2014 retry once`,
|
|
44600
|
+
{ cause: err }
|
|
44601
|
+
);
|
|
44602
|
+
}
|
|
44603
|
+
return new HttpTransportError(
|
|
44604
|
+
"unknown",
|
|
44605
|
+
`${method} ${url} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
44606
|
+
{ cause: err }
|
|
44607
|
+
);
|
|
44608
|
+
}
|
|
44342
44609
|
|
|
44343
44610
|
// src-ts/browser/keyLoader.ts
|
|
44611
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44612
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44344
44613
|
var NOT_AVAILABLE = "keyLoader is not available in the browser bundle \u2014 pass `agentKey` explicitly to Atbash.fromConfig or use `new Atbash(privkey, opts)`.";
|
|
44345
44614
|
function resolveKeyPath(_input) {
|
|
44346
44615
|
throw new Error(NOT_AVAILABLE);
|
|
@@ -44349,17 +44618,36 @@ function loadAgentFromFile(_keyPath) {
|
|
|
44349
44618
|
throw new Error(NOT_AVAILABLE);
|
|
44350
44619
|
}
|
|
44351
44620
|
|
|
44621
|
+
// src-ts/decision.ts
|
|
44622
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44623
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44624
|
+
|
|
44352
44625
|
// src-ts/normalize.ts
|
|
44626
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44627
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44628
|
+
function wireText(raw2, fallback = "") {
|
|
44629
|
+
if (raw2 === null || raw2 === void 0) return fallback;
|
|
44630
|
+
if (typeof raw2 === "object" || typeof raw2 === "function") return fallback;
|
|
44631
|
+
return String(raw2);
|
|
44632
|
+
}
|
|
44633
|
+
function wireNumber(raw2, fallback = 0) {
|
|
44634
|
+
if (raw2 === null || raw2 === void 0) return fallback;
|
|
44635
|
+
if (typeof raw2 === "object" || typeof raw2 === "function") return fallback;
|
|
44636
|
+
return Number(raw2);
|
|
44637
|
+
}
|
|
44353
44638
|
function normalizeVerdict(raw2) {
|
|
44354
44639
|
if (raw2 === null || raw2 === void 0) return "No verdict";
|
|
44355
|
-
const v =
|
|
44640
|
+
const v = wireText(raw2).trim().toUpperCase();
|
|
44356
44641
|
if (v === "ALLOW" || v === "GREEN") return "ALLOW";
|
|
44357
44642
|
if (v === "HOLD" || v === "YELLOW") return "HOLD";
|
|
44358
44643
|
if (v === "BLOCK" || v === "RED") return "BLOCK";
|
|
44359
44644
|
return "HOLD";
|
|
44360
44645
|
}
|
|
44646
|
+
function normalizeActionType(raw2) {
|
|
44647
|
+
return typeof raw2 === "string" ? raw2.trim().toLowerCase() : "";
|
|
44648
|
+
}
|
|
44361
44649
|
function normalizeStatus(raw2) {
|
|
44362
|
-
const s2 =
|
|
44650
|
+
const s2 = wireText(raw2).toLowerCase();
|
|
44363
44651
|
if (s2 === "pending" || s2 === "answered" || s2 === "error") return s2;
|
|
44364
44652
|
return "error";
|
|
44365
44653
|
}
|
|
@@ -44374,7 +44662,137 @@ function pubkeyToHex(val) {
|
|
|
44374
44662
|
return "";
|
|
44375
44663
|
}
|
|
44376
44664
|
|
|
44665
|
+
// src-ts/decision.ts
|
|
44666
|
+
function isRecord(value) {
|
|
44667
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
44668
|
+
}
|
|
44669
|
+
function allowSignalsPermit(data) {
|
|
44670
|
+
const signals = [];
|
|
44671
|
+
if (Object.hasOwn(data, "allow")) signals.push(data.allow);
|
|
44672
|
+
if (isRecord(data.decision) && Object.hasOwn(data.decision, "allow")) {
|
|
44673
|
+
signals.push(data.decision.allow);
|
|
44674
|
+
}
|
|
44675
|
+
return signals.length === 0 || signals.every((value) => value === true);
|
|
44676
|
+
}
|
|
44677
|
+
function explicitRefusal(data) {
|
|
44678
|
+
let hold = false;
|
|
44679
|
+
for (const source of decisionSources(data)) {
|
|
44680
|
+
const verdict = verdictOf(source);
|
|
44681
|
+
if (verdict === "BLOCK" || verdict === "RED") return "BLOCK";
|
|
44682
|
+
if (verdict === "HOLD" || verdict === "YELLOW") hold = true;
|
|
44683
|
+
const actionType = actionTypeOf(source);
|
|
44684
|
+
if (actionType === "block") return "BLOCK";
|
|
44685
|
+
if (actionType === "hold_for_user_confirm") hold = true;
|
|
44686
|
+
}
|
|
44687
|
+
if (!allowSignalsPermit(data)) return "BLOCK";
|
|
44688
|
+
return hold ? "HOLD" : "";
|
|
44689
|
+
}
|
|
44690
|
+
function decisionSources(data) {
|
|
44691
|
+
return [data, isRecord(data.decision) ? data.decision : {}];
|
|
44692
|
+
}
|
|
44693
|
+
function verdictOf(source) {
|
|
44694
|
+
return typeof source.verdict === "string" ? source.verdict.trim().toUpperCase() : "";
|
|
44695
|
+
}
|
|
44696
|
+
function actionTypeRank(actionType) {
|
|
44697
|
+
if (actionType === "block") return 4;
|
|
44698
|
+
if (actionType === "hold_for_user_confirm") return 3;
|
|
44699
|
+
if (actionType === "") return 1;
|
|
44700
|
+
if (actionType === "allow") return 0;
|
|
44701
|
+
return 2;
|
|
44702
|
+
}
|
|
44703
|
+
function actionTypeOf(source) {
|
|
44704
|
+
let winner = "";
|
|
44705
|
+
for (const key3 of ["action_type", "actionType"]) {
|
|
44706
|
+
const raw2 = source[key3];
|
|
44707
|
+
if (raw2 === void 0 || raw2 === null) continue;
|
|
44708
|
+
const actionType = normalizeActionType(raw2);
|
|
44709
|
+
if (actionTypeRank(actionType) > actionTypeRank(winner)) winner = actionType;
|
|
44710
|
+
}
|
|
44711
|
+
return winner;
|
|
44712
|
+
}
|
|
44713
|
+
function wireActionType(data) {
|
|
44714
|
+
for (const source of decisionSources(data)) {
|
|
44715
|
+
const actionType = actionTypeOf(source);
|
|
44716
|
+
if (actionType !== "") return actionType;
|
|
44717
|
+
}
|
|
44718
|
+
return "";
|
|
44719
|
+
}
|
|
44720
|
+
function isAuditTier(data) {
|
|
44721
|
+
const absentVerdict = data.verdict === null || data.verdict === void 0;
|
|
44722
|
+
return absentVerdict && data.status === "logged";
|
|
44723
|
+
}
|
|
44724
|
+
function isAuditTierBody(data) {
|
|
44725
|
+
return isAuditTier(data);
|
|
44726
|
+
}
|
|
44727
|
+
function canonicalAllow(data) {
|
|
44728
|
+
if (explicitRefusal(data) !== "") return false;
|
|
44729
|
+
const actionType = wireActionType(data);
|
|
44730
|
+
if (actionType && actionType !== "allow") return false;
|
|
44731
|
+
if (isAuditTier(data)) return true;
|
|
44732
|
+
if (typeof data.verdict !== "string") return false;
|
|
44733
|
+
const verdict = data.verdict.trim().toUpperCase();
|
|
44734
|
+
return verdict === "ALLOW" || verdict === "GREEN";
|
|
44735
|
+
}
|
|
44736
|
+
|
|
44737
|
+
// src-ts/opentel/events.ts
|
|
44738
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44739
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44740
|
+
var SLOW_MS = 1500;
|
|
44741
|
+
var SUCCESS_SAMPLE_RATE = 10;
|
|
44742
|
+
var logger2 = null;
|
|
44743
|
+
var eventsEnabled = false;
|
|
44744
|
+
var sdkVersion = "";
|
|
44745
|
+
var eventSource = "sdk";
|
|
44746
|
+
var hashAgentKey = null;
|
|
44747
|
+
function eventsOptedOut() {
|
|
44748
|
+
const flag = process.env.ATBASH_TELEMETRY_EVENTS_DISABLED?.trim().toLowerCase();
|
|
44749
|
+
return Boolean(flag && ["1", "true", "yes", "on"].includes(flag));
|
|
44750
|
+
}
|
|
44751
|
+
var SOURCE_SHAPE = /^(?:sdk|cli|plugin:[a-z0-9][a-z0-9._-]{0,31})$/;
|
|
44752
|
+
function configureEvents(next, opts = {}) {
|
|
44753
|
+
logger2 = next;
|
|
44754
|
+
eventsEnabled = next !== null && !eventsOptedOut();
|
|
44755
|
+
if (opts.version) sdkVersion = opts.version;
|
|
44756
|
+
if (opts.source && SOURCE_SHAPE.test(opts.source)) eventSource = opts.source;
|
|
44757
|
+
hashAgentKey = opts.hashAgentKey ?? null;
|
|
44758
|
+
}
|
|
44759
|
+
function eventsAreOn() {
|
|
44760
|
+
return eventsEnabled && logger2 !== null;
|
|
44761
|
+
}
|
|
44762
|
+
function sampleRateFor(e) {
|
|
44763
|
+
if (e.status === "error") return 1;
|
|
44764
|
+
if (e.durationMs >= SLOW_MS) return 1;
|
|
44765
|
+
return Math.random() < 1 / SUCCESS_SAMPLE_RATE ? SUCCESS_SAMPLE_RATE : 0;
|
|
44766
|
+
}
|
|
44767
|
+
function recordEvent(e) {
|
|
44768
|
+
if (!eventsAreOn()) return;
|
|
44769
|
+
const sampleRate = sampleRateFor(e);
|
|
44770
|
+
if (sampleRate === 0) return;
|
|
44771
|
+
try {
|
|
44772
|
+
const attributes = {
|
|
44773
|
+
"function.name": e.functionName,
|
|
44774
|
+
"duration_ms": Math.round(e.durationMs),
|
|
44775
|
+
status: e.status,
|
|
44776
|
+
source: eventSource,
|
|
44777
|
+
// Honeycomb reweights counts and percentiles by this. It is per-event
|
|
44778
|
+
// because the sampling is biased by outcome and latency.
|
|
44779
|
+
sampleRate
|
|
44780
|
+
};
|
|
44781
|
+
if (sdkVersion) attributes["sdk.version"] = sdkVersion;
|
|
44782
|
+
if (e.agentPubkey && hashAgentKey) attributes["agent.hash"] = hashAgentKey(e.agentPubkey);
|
|
44783
|
+
if (e.chain) attributes["chain"] = e.chain;
|
|
44784
|
+
if (e.errorClass) attributes["error.class"] = e.errorClass;
|
|
44785
|
+
if (e.errorStatus !== void 0) attributes["error.status"] = e.errorStatus;
|
|
44786
|
+
if (e.errorPath) attributes["error.path"] = e.errorPath;
|
|
44787
|
+
if (e.outcome) attributes["outcome"] = e.outcome;
|
|
44788
|
+
logger2.emit({ body: e.functionName, attributes });
|
|
44789
|
+
} catch {
|
|
44790
|
+
}
|
|
44791
|
+
}
|
|
44792
|
+
|
|
44377
44793
|
// src-ts/browser/opentel/telemetry.ts
|
|
44794
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44795
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44378
44796
|
function setupTelemetry(_config) {
|
|
44379
44797
|
}
|
|
44380
44798
|
function recordCall(_functionName, _source, _agentPubkey) {
|
|
@@ -44387,6 +44805,8 @@ async function shutdownTelemetry() {
|
|
|
44387
44805
|
}
|
|
44388
44806
|
|
|
44389
44807
|
// src-ts/browser/userConfig.ts
|
|
44808
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44809
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44390
44810
|
var NOT_AVAILABLE2 = "userConfig file I/O is not available in the browser bundle.";
|
|
44391
44811
|
function getConfigDir() {
|
|
44392
44812
|
throw new Error(NOT_AVAILABLE2);
|
|
@@ -44403,11 +44823,47 @@ function saveUserConfig(_) {
|
|
|
44403
44823
|
function resolve(_key, flagValue) {
|
|
44404
44824
|
return flagValue ?? "";
|
|
44405
44825
|
}
|
|
44826
|
+
function forcedChainNetwork(flagValue) {
|
|
44827
|
+
return flagValue === "public" || flagValue === "private" ? flagValue : void 0;
|
|
44828
|
+
}
|
|
44829
|
+
function agentKeyFromEnv() {
|
|
44830
|
+
return "";
|
|
44831
|
+
}
|
|
44832
|
+
function strandedAgentKey() {
|
|
44833
|
+
return "";
|
|
44834
|
+
}
|
|
44406
44835
|
|
|
44407
44836
|
// src-ts/client.ts
|
|
44408
44837
|
function generateToolCallId() {
|
|
44409
44838
|
return `tc-${Date.now()}-${randomHex(4)}`;
|
|
44410
44839
|
}
|
|
44840
|
+
function resolveConstructorChain(options) {
|
|
44841
|
+
if (options.chain) return options.chain;
|
|
44842
|
+
const hasNodeUrls = options.nodeUrls !== void 0;
|
|
44843
|
+
const hasBrid = options.blockchainRid !== void 0;
|
|
44844
|
+
if (hasNodeUrls !== hasBrid) {
|
|
44845
|
+
throw new Error(
|
|
44846
|
+
'nodeUrls and blockchainRid must be provided together \u2014 passing one without the other 404s every chain request. Prefer `chain: PUBLIC_CHAIN | PRIVATE_CHAIN` or `network: "public" | "private"`.'
|
|
44847
|
+
);
|
|
44848
|
+
}
|
|
44849
|
+
if (hasNodeUrls && hasBrid) {
|
|
44850
|
+
const brid = options.blockchainRid;
|
|
44851
|
+
const derivedNetwork = options.network ?? (brid === PUBLIC_CHAIN.blockchainRid ? "public" : brid === PRIVATE_CHAIN.blockchainRid ? "private" : "private");
|
|
44852
|
+
return {
|
|
44853
|
+
network: derivedNetwork,
|
|
44854
|
+
blockchainRid: brid,
|
|
44855
|
+
nodeUrls: options.nodeUrls
|
|
44856
|
+
};
|
|
44857
|
+
}
|
|
44858
|
+
return chainForNetwork(options.network ?? forcedChainNetwork() ?? "private");
|
|
44859
|
+
}
|
|
44860
|
+
function errorDetail(err) {
|
|
44861
|
+
if (!(err instanceof AtbashAPIError)) return {};
|
|
44862
|
+
return {
|
|
44863
|
+
errorStatus: err.status,
|
|
44864
|
+
...err.path ? { errorPath: err.path } : {}
|
|
44865
|
+
};
|
|
44866
|
+
}
|
|
44411
44867
|
var Atbash = class _Atbash {
|
|
44412
44868
|
auth;
|
|
44413
44869
|
endpoint;
|
|
@@ -44421,6 +44877,13 @@ var Atbash = class _Atbash {
|
|
|
44421
44877
|
orgEncryptionPubKey;
|
|
44422
44878
|
/** When true (default), `auditToolCall` denies on any error. */
|
|
44423
44879
|
failClosed;
|
|
44880
|
+
/** When true (default), an unenforced (audit-tier) answer is refused. */
|
|
44881
|
+
requireEnforcement;
|
|
44882
|
+
/** Overall deadline for one auditToolCall decision, in ms. */
|
|
44883
|
+
decisionTimeoutMs;
|
|
44884
|
+
/** Org key learned from the last agent-exists check, for this agent only. */
|
|
44885
|
+
_orgKeyFromChain = null;
|
|
44886
|
+
debug;
|
|
44424
44887
|
logger;
|
|
44425
44888
|
http;
|
|
44426
44889
|
/**
|
|
@@ -44429,28 +44892,114 @@ var Atbash = class _Atbash {
|
|
|
44429
44892
|
*/
|
|
44430
44893
|
_chainCache = /* @__PURE__ */ new Map();
|
|
44431
44894
|
/**
|
|
44432
|
-
*
|
|
44433
|
-
*
|
|
44434
|
-
|
|
44895
|
+
* The chain the constructor settled on. Used only where a lookup returns no
|
|
44896
|
+
* answer — see {@link resolveChainFromMap}.
|
|
44897
|
+
*/
|
|
44898
|
+
_defaultChain;
|
|
44899
|
+
/**
|
|
44900
|
+
* True when the caller named a chain outright — `chain`, `network`, or the
|
|
44901
|
+
* paired `blockchainRid` + `nodeUrls`.
|
|
44902
|
+
*
|
|
44903
|
+
* Such a client is never re-pointed: not by the migration switch, and not by
|
|
44904
|
+
* where an org turns out to live. Naming a chain is the caller saying "talk
|
|
44905
|
+
* to this one", and silently routing elsewhere would make the argument a
|
|
44906
|
+
* suggestion. A client that names nothing is the one that follows the org.
|
|
44435
44907
|
*/
|
|
44436
|
-
|
|
44908
|
+
_explicitChain;
|
|
44909
|
+
/**
|
|
44910
|
+
* The fleet-wide chain switch, read once at construction. `resolve()` hits
|
|
44911
|
+
* the config file on disk, so re-reading it per call would put a file read
|
|
44912
|
+
* on every judge.
|
|
44913
|
+
*/
|
|
44914
|
+
_forcedNetwork;
|
|
44915
|
+
/**
|
|
44916
|
+
* Short-TTL cache for `/api/ai/exists`. The `registered` field is
|
|
44917
|
+
* monotonic (once true, stays true), so most calls in a burst re-fetch
|
|
44918
|
+
* data that hasn't changed. The `org_encryption_pubkey` field CAN change
|
|
44919
|
+
* — an org toggling encryption mid-session — so the TTL is deliberately
|
|
44920
|
+
* short (see `AGENT_EXISTS_TTL_MS`). Keyed by (pubkey, network) so
|
|
44921
|
+
* cross-agent / cross-network calls don't collide.
|
|
44922
|
+
*/
|
|
44923
|
+
_agentExistsCache = null;
|
|
44924
|
+
static AGENT_EXISTS_TTL_MS = 5e3;
|
|
44925
|
+
/** Guards `logEnvironmentOnce` — hosts construct several clients. */
|
|
44926
|
+
static environmentLogged = false;
|
|
44437
44927
|
constructor(privkey, options = {}) {
|
|
44438
44928
|
this.auth = native.loadAgent(privkey);
|
|
44439
|
-
|
|
44440
|
-
|
|
44441
|
-
|
|
44929
|
+
const validated = validateJudgeEndpoint(
|
|
44930
|
+
options.verifyPubKey ? {
|
|
44931
|
+
policy: "self-hosted",
|
|
44932
|
+
endpoint: options.endpoint ?? DEFAULT_ENDPOINT,
|
|
44933
|
+
verifyPubKey: options.verifyPubKey
|
|
44934
|
+
} : { endpoint: options.endpoint }
|
|
44935
|
+
);
|
|
44936
|
+
this.endpoint = validated.url;
|
|
44937
|
+
const resolvedChain = resolveConstructorChain(options);
|
|
44938
|
+
this.nodeUrls = [...resolvedChain.nodeUrls];
|
|
44939
|
+
this.blockchainRid = resolvedChain.blockchainRid;
|
|
44940
|
+
this._defaultChain = resolvedChain;
|
|
44941
|
+
this._explicitChain = options.chain !== void 0 || options.network !== void 0 || options.blockchainRid !== void 0 && options.nodeUrls !== void 0;
|
|
44942
|
+
this._forcedNetwork = forcedChainNetwork();
|
|
44442
44943
|
this.orgName = options.orgName;
|
|
44443
|
-
this.verifyPubKey =
|
|
44944
|
+
this.verifyPubKey = validated.verifyPubKey ?? void 0;
|
|
44444
44945
|
this.orgEncryptionPubKey = options.orgEncryptionPubKey;
|
|
44445
44946
|
this.failClosed = options.failClosed !== false;
|
|
44947
|
+
this.requireEnforcement = options.requireEnforcement !== false;
|
|
44948
|
+
this.decisionTimeoutMs = options.decisionTimeoutMs ?? DEFAULT_DECISION_TIMEOUT_MS;
|
|
44949
|
+
this.debug = options.debug === true;
|
|
44446
44950
|
this.logger = options.logger ?? {};
|
|
44447
|
-
this.http = new HttpClient(this.endpoint, options.timeoutMs ??
|
|
44951
|
+
this.http = new HttpClient(this.endpoint, options.timeoutMs ?? 12e4);
|
|
44952
|
+
this.logEnvironmentOnce();
|
|
44448
44953
|
if (this.endpoint !== DEFAULT_ENDPOINT) {
|
|
44449
44954
|
this.logger.warn?.("[atbash] running on non-default judge endpoint", {
|
|
44450
44955
|
endpoint: this.endpoint,
|
|
44451
44956
|
verifying: this.verifyPubKey ? "with response-signature pubkey configured" : "without signature verification"
|
|
44452
44957
|
});
|
|
44453
44958
|
}
|
|
44959
|
+
if (isAllowlistedJudgeHost(this.endpoint)) {
|
|
44960
|
+
try {
|
|
44961
|
+
setupTelemetry({
|
|
44962
|
+
enabled: true,
|
|
44963
|
+
endpoint: this.endpoint,
|
|
44964
|
+
getAuthHeaders: () => this.authHeaders()
|
|
44965
|
+
});
|
|
44966
|
+
} catch (err) {
|
|
44967
|
+
this.logger.warn?.(
|
|
44968
|
+
"[atbash] telemetry setup failed \u2014 continuing without metrics",
|
|
44969
|
+
{ error: String(err) }
|
|
44970
|
+
);
|
|
44971
|
+
}
|
|
44972
|
+
} else {
|
|
44973
|
+
this.logger.info?.(
|
|
44974
|
+
"[atbash] telemetry disabled \u2014 the agent bearer is only sent to hosts that already receive it, and this judge endpoint is not one",
|
|
44975
|
+
{ endpoint: this.endpoint }
|
|
44976
|
+
);
|
|
44977
|
+
}
|
|
44978
|
+
}
|
|
44979
|
+
/**
|
|
44980
|
+
* Say which environment this build talks to, once per process.
|
|
44981
|
+
*
|
|
44982
|
+
* The endpoint and both chain RIDs are compiled in, chosen by the npm tag,
|
|
44983
|
+
* and no configuration repoints a released build. So installing the build
|
|
44984
|
+
* for the wrong environment is invisible: the plugin loads, the hook fires,
|
|
44985
|
+
* and every judge call fails because the agent does not exist on the chain
|
|
44986
|
+
* this build targets. Organisation names are not unique across environments
|
|
44987
|
+
* either, so an org resolving is not evidence the build is right.
|
|
44988
|
+
*/
|
|
44989
|
+
logEnvironmentOnce() {
|
|
44990
|
+
if (_Atbash.environmentLogged) return;
|
|
44991
|
+
_Atbash.environmentLogged = true;
|
|
44992
|
+
const brief = (rid) => rid ? `${rid.slice(0, 8)}\u2026` : "(unset)";
|
|
44993
|
+
this.logger.info?.(
|
|
44994
|
+
`[atbash] environment \u2014 judge=${this.endpoint} publicChain=${brief(native.DEFAULT_BLOCKCHAIN_RID)} privateChain=${brief(native.DEFAULT_PRIVATE_BLOCKCHAIN_RID)} activeChain=${brief(this.blockchainRid)} responseSignatureCheck=${this.verifyPubKey ? "on" : "off"}`,
|
|
44995
|
+
{
|
|
44996
|
+
judgeEndpoint: this.endpoint,
|
|
44997
|
+
publicBlockchainRid: native.DEFAULT_BLOCKCHAIN_RID,
|
|
44998
|
+
privateBlockchainRid: native.DEFAULT_PRIVATE_BLOCKCHAIN_RID,
|
|
44999
|
+
activeBlockchainRid: this.blockchainRid,
|
|
45000
|
+
responseSignatureCheck: Boolean(this.verifyPubKey)
|
|
45001
|
+
}
|
|
45002
|
+
);
|
|
44454
45003
|
}
|
|
44455
45004
|
/**
|
|
44456
45005
|
* Construct from resolved config: explicit overrides → env vars → the
|
|
@@ -44460,21 +45009,116 @@ var Atbash = class _Atbash {
|
|
|
44460
45009
|
* validated against the trusted allowlist / self-hosted policy; a
|
|
44461
45010
|
* self-hosted endpoint's `verifyPubKey` becomes the client default.
|
|
44462
45011
|
*/
|
|
45012
|
+
/**
|
|
45013
|
+
* Decide which key this client signs as.
|
|
45014
|
+
*
|
|
45015
|
+
* Most specific wins: a key passed in code, then a key file the host named,
|
|
45016
|
+
* then the environment, then the default key file. `config.json` is absent
|
|
45017
|
+
* from that list on purpose — it is a settings file, writable by anything
|
|
45018
|
+
* that can write the user's home and read by every Atbash integration on the
|
|
45019
|
+
* machine, so letting it name the key meant one stray value silently
|
|
45020
|
+
* re-pointed who each of them signed as.
|
|
45021
|
+
*
|
|
45022
|
+
* A named `keyPath` that does not exist throws rather than falling through.
|
|
45023
|
+
* The caller said which file holds its identity; quietly signing as a
|
|
45024
|
+
* different one is the outcome worth refusing.
|
|
45025
|
+
*
|
|
45026
|
+
* @param options - The `fromConfig` options, read for `agentKey` and `keyPath`.
|
|
45027
|
+
* @returns The resolved agent identity.
|
|
45028
|
+
* @throws When a named key file is missing, or no identity can be found.
|
|
45029
|
+
*/
|
|
45030
|
+
static resolveIdentity(options) {
|
|
45031
|
+
if (options.agentKey) return native.loadAgent(options.agentKey);
|
|
45032
|
+
if (options.keyPath) return loadAgentFromFile(options.keyPath);
|
|
45033
|
+
const fromEnv = agentKeyFromEnv();
|
|
45034
|
+
if (fromEnv) return native.loadAgent(fromEnv);
|
|
45035
|
+
try {
|
|
45036
|
+
return loadAgentFromFile();
|
|
45037
|
+
} catch (err) {
|
|
45038
|
+
throw _Atbash.explainStrandedKey(err);
|
|
45039
|
+
}
|
|
45040
|
+
}
|
|
45041
|
+
/**
|
|
45042
|
+
* Add the one thing a machine with no key file needs to hear.
|
|
45043
|
+
*
|
|
45044
|
+
* This is the only path where the operator cannot see what happened: no key
|
|
45045
|
+
* file, and the key they are looking for sits in `config.json`, which no
|
|
45046
|
+
* longer selects the identity. A bare "key file not found" sends them hunting
|
|
45047
|
+
* for a key they already have. Only this branch gets the hint — a caller who
|
|
45048
|
+
* named a `keyPath` is told about that path, where a stranded key is noise.
|
|
45049
|
+
*
|
|
45050
|
+
* @param err - The "key file not found" error from the default lookup.
|
|
45051
|
+
* @returns The same error, or one that also names the key in config.json.
|
|
45052
|
+
*/
|
|
45053
|
+
static explainStrandedKey(err) {
|
|
45054
|
+
const stranded = strandedAgentKey();
|
|
45055
|
+
if (!stranded) return err;
|
|
45056
|
+
let identity;
|
|
45057
|
+
try {
|
|
45058
|
+
identity = native.derivePublicKey(stranded);
|
|
45059
|
+
} catch {
|
|
45060
|
+
identity = "(unreadable)";
|
|
45061
|
+
}
|
|
45062
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
45063
|
+
return new Error(
|
|
45064
|
+
`${message}
|
|
45065
|
+
config.json still holds an "agentKey" (${identity}), but a settings file no longer chooses the signing key. Move it into one of the key files above, or set ATBASH_AGENT_KEY.`
|
|
45066
|
+
);
|
|
45067
|
+
}
|
|
45068
|
+
/**
|
|
45069
|
+
* Say so when `config.json` still holds an agent key.
|
|
45070
|
+
*
|
|
45071
|
+
* Nothing signs with it any more, and silence would leave an operator
|
|
45072
|
+
* believing one identity is in force while another is. The pubkey is named,
|
|
45073
|
+
* not the key, so the line is safe in a log.
|
|
45074
|
+
*
|
|
45075
|
+
* @param logger - The host logger, when one was supplied.
|
|
45076
|
+
*/
|
|
45077
|
+
static warnOnStrandedKey(logger3) {
|
|
45078
|
+
const stranded = strandedAgentKey();
|
|
45079
|
+
if (!stranded) return;
|
|
45080
|
+
let identity;
|
|
45081
|
+
try {
|
|
45082
|
+
identity = native.derivePublicKey(stranded);
|
|
45083
|
+
} catch {
|
|
45084
|
+
identity = "(unreadable)";
|
|
45085
|
+
}
|
|
45086
|
+
logger3?.warn?.(
|
|
45087
|
+
`[atbash] "agentKey" in config.json is ignored \u2014 settings do not choose the signing key. It holds ${identity}; this client signs as the key file or ATBASH_AGENT_KEY instead. Move it into the key file, or delete the field, to silence this.`
|
|
45088
|
+
);
|
|
45089
|
+
}
|
|
44463
45090
|
static fromConfig(options = {}) {
|
|
45091
|
+
const configuredEndpoint = resolve("judgeEndpoint") || void 0;
|
|
45092
|
+
const configuredVerifyPubKey = resolve("judgeVerifyPubKey") || void 0;
|
|
45093
|
+
if (!options.judge && configuredVerifyPubKey && !configuredEndpoint) {
|
|
45094
|
+
throw new Error(
|
|
45095
|
+
"judgeVerifyPubKey / ATBASH_JUDGE_VERIFY_PUBKEY is set but no judge endpoint is configured: set judgeEndpoint / ATBASH_ENDPOINT to the self-hosted judge"
|
|
45096
|
+
);
|
|
45097
|
+
}
|
|
44464
45098
|
const validated = validateJudgeEndpoint(
|
|
44465
|
-
options.judge ??
|
|
45099
|
+
options.judge ?? (configuredVerifyPubKey && configuredEndpoint ? {
|
|
45100
|
+
policy: "self-hosted",
|
|
45101
|
+
endpoint: configuredEndpoint,
|
|
45102
|
+
verifyPubKey: configuredVerifyPubKey
|
|
45103
|
+
} : { endpoint: configuredEndpoint })
|
|
44466
45104
|
);
|
|
44467
|
-
const
|
|
44468
|
-
|
|
44469
|
-
const blockchainRid = resolve("blockchainRid", options.blockchainRid) || void 0;
|
|
45105
|
+
const auth = _Atbash.resolveIdentity(options);
|
|
45106
|
+
_Atbash.warnOnStrandedKey(options.logger);
|
|
44470
45107
|
return new _Atbash(auth.privkey, {
|
|
44471
45108
|
endpoint: validated.url,
|
|
44472
|
-
|
|
45109
|
+
chain: options.chain,
|
|
45110
|
+
network: options.network,
|
|
45111
|
+
blockchainRid: options.blockchainRid,
|
|
44473
45112
|
timeoutMs: options.timeoutMs,
|
|
44474
45113
|
nodeUrls: options.nodeUrls,
|
|
44475
45114
|
orgName: options.orgName,
|
|
44476
45115
|
verifyPubKey: validated.verifyPubKey ?? void 0,
|
|
44477
45116
|
failClosed: options.failClosed,
|
|
45117
|
+
requireEnforcement: options.requireEnforcement,
|
|
45118
|
+
decisionTimeoutMs: options.decisionTimeoutMs,
|
|
45119
|
+
// ATBASH_DEBUG lets an operator turn diagnostics on without editing a
|
|
45120
|
+
// host's plugin config, which is usually the harder half.
|
|
45121
|
+
debug: options.debug ?? /^(1|true|yes)$/i.test(resolve("debug")),
|
|
44478
45122
|
logger: options.logger
|
|
44479
45123
|
});
|
|
44480
45124
|
}
|
|
@@ -44495,17 +45139,41 @@ var Atbash = class _Atbash {
|
|
|
44495
45139
|
*/
|
|
44496
45140
|
async checkAgentExists(pubkey, opts) {
|
|
44497
45141
|
const pk = pubkey ?? this.auth.pubkey;
|
|
45142
|
+
const network = opts?.network;
|
|
45143
|
+
const now = Date.now();
|
|
45144
|
+
const cached = this._agentExistsCache;
|
|
45145
|
+
if (cached && cached.pubkey === pk && cached.network === network && cached.expiresAt > now) {
|
|
45146
|
+
if (pk === this.auth.pubkey) {
|
|
45147
|
+
this._orgKeyFromChain = cached.orgKey;
|
|
45148
|
+
}
|
|
45149
|
+
return cached.registered;
|
|
45150
|
+
}
|
|
44498
45151
|
return this.track("checkAgentExists", pk, async () => {
|
|
44499
45152
|
const query = { pubkey: pk };
|
|
44500
|
-
if (
|
|
45153
|
+
if (network) query.network = network;
|
|
45154
|
+
const brid = network ? this.bridFromChainOpts({ network }) : await this.defaultOrgBrid();
|
|
44501
45155
|
const resp = await this.http.get(
|
|
44502
45156
|
"/api/ai/exists",
|
|
44503
45157
|
query,
|
|
44504
|
-
this.authHeaders()
|
|
45158
|
+
this.authHeaders(brid)
|
|
44505
45159
|
);
|
|
44506
45160
|
await this.raiseIfError(resp);
|
|
44507
45161
|
const data = await this.json(resp);
|
|
44508
|
-
|
|
45162
|
+
const registered = Boolean(data?.registered);
|
|
45163
|
+
const orgKey = typeof data?.org_encryption_pubkey === "string" && data.org_encryption_pubkey ? data.org_encryption_pubkey : null;
|
|
45164
|
+
if (registered) {
|
|
45165
|
+
this._agentExistsCache = {
|
|
45166
|
+
pubkey: pk,
|
|
45167
|
+
network,
|
|
45168
|
+
expiresAt: Date.now() + _Atbash.AGENT_EXISTS_TTL_MS,
|
|
45169
|
+
registered,
|
|
45170
|
+
orgKey
|
|
45171
|
+
};
|
|
45172
|
+
}
|
|
45173
|
+
if (pk === this.auth.pubkey) {
|
|
45174
|
+
this._orgKeyFromChain = orgKey;
|
|
45175
|
+
}
|
|
45176
|
+
return registered;
|
|
44509
45177
|
});
|
|
44510
45178
|
}
|
|
44511
45179
|
/* ── log_tool_call (sign-only) ─────────────────────────────────────────── */
|
|
@@ -44534,8 +45202,8 @@ var Atbash = class _Atbash {
|
|
|
44534
45202
|
};
|
|
44535
45203
|
}
|
|
44536
45204
|
const toolCallId = generateToolCallId();
|
|
44537
|
-
const brid = this.bridFromChainOpts(options.chainOpts);
|
|
44538
|
-
const orgKey = options.orgEncryptionPubKey ?? this.orgEncryptionPubKey;
|
|
45205
|
+
const brid = options.chainOpts?.blockchainRid || options.chainOpts?.network ? this.bridFromChainOpts(options.chainOpts) : await this.defaultOrgBrid() ?? this.blockchainRid;
|
|
45206
|
+
const orgKey = options.orgEncryptionPubKey ?? this.orgEncryptionPubKey ?? this._orgKeyFromChain;
|
|
44539
45207
|
try {
|
|
44540
45208
|
const signedHex = orgKey ? signEncryptedToolCall(
|
|
44541
45209
|
toolCallId,
|
|
@@ -44570,24 +45238,42 @@ var Atbash = class _Atbash {
|
|
|
44570
45238
|
* response bytes via the Rust core's `verifySignature`.
|
|
44571
45239
|
*/
|
|
44572
45240
|
async judgeAction(action, context = "", options = {}) {
|
|
44573
|
-
return this.track(
|
|
44574
|
-
|
|
44575
|
-
|
|
44576
|
-
|
|
44577
|
-
|
|
45241
|
+
return this.track("judgeAction", this.auth.pubkey, async () => {
|
|
45242
|
+
try {
|
|
45243
|
+
return await this._judgeAction(action, context, options);
|
|
45244
|
+
} catch (err) {
|
|
45245
|
+
if (!isEncryptionStateMismatch(err)) throw err;
|
|
45246
|
+
this._orgKeyFromChain = null;
|
|
45247
|
+
return await this._judgeAction(action, context, options);
|
|
45248
|
+
}
|
|
45249
|
+
});
|
|
44578
45250
|
}
|
|
44579
45251
|
async _judgeAction(action, context, options) {
|
|
44580
45252
|
if (!action?.trim()) {
|
|
44581
45253
|
throw new Error("action is required and cannot be empty.");
|
|
44582
45254
|
}
|
|
44583
45255
|
let chainOpts = options.chainOpts;
|
|
44584
|
-
if (options.orgName) {
|
|
44585
|
-
|
|
44586
|
-
|
|
44587
|
-
|
|
44588
|
-
|
|
44589
|
-
|
|
44590
|
-
|
|
45256
|
+
if (options.orgName && this._explicitChain) {
|
|
45257
|
+
chainOpts = options.chainOpts ?? { network: this._defaultChain.network };
|
|
45258
|
+
} else if (options.orgName && this.forcedNetwork()) {
|
|
45259
|
+
chainOpts = { network: this.forcedNetwork() };
|
|
45260
|
+
} else if (options.orgName) {
|
|
45261
|
+
const cached = this._chainCache.get(options.orgName);
|
|
45262
|
+
if (cached) {
|
|
45263
|
+
chainOpts = { network: cached.network };
|
|
45264
|
+
} else {
|
|
45265
|
+
const mapNetwork = await this.getActiveNetworkForOrg(options.orgName);
|
|
45266
|
+
if (mapNetwork) {
|
|
45267
|
+
const chain = mapNetwork === "private" ? PRIVATE_CHAIN : PUBLIC_CHAIN;
|
|
45268
|
+
this._chainCache.set(options.orgName, chain);
|
|
45269
|
+
chainOpts = { network: mapNetwork };
|
|
45270
|
+
} else if (!chainOpts?.blockchainRid) {
|
|
45271
|
+
const resolved = await this.resolveChainFromMap(
|
|
45272
|
+
options.orgName,
|
|
45273
|
+
null
|
|
45274
|
+
);
|
|
45275
|
+
chainOpts = { ...chainOpts, network: resolved.network };
|
|
45276
|
+
}
|
|
44591
45277
|
}
|
|
44592
45278
|
}
|
|
44593
45279
|
const brid = this.bridFromChainOpts(chainOpts);
|
|
@@ -44599,18 +45285,15 @@ var Atbash = class _Atbash {
|
|
|
44599
45285
|
if (!logResult.success || !logResult.toolCallId || !logResult.signedHex) {
|
|
44600
45286
|
throw new Error(logResult.error || "Failed to sign log_tool_call");
|
|
44601
45287
|
}
|
|
44602
|
-
|
|
44603
|
-
|
|
44604
|
-
|
|
44605
|
-
|
|
44606
|
-
|
|
44607
|
-
|
|
44608
|
-
|
|
44609
|
-
|
|
44610
|
-
|
|
44611
|
-
brid
|
|
44612
|
-
);
|
|
44613
|
-
}
|
|
45288
|
+
const judgmentId = generateToolCallId();
|
|
45289
|
+
const signedJudgeAction = native.signJudgeAction(
|
|
45290
|
+
judgmentId,
|
|
45291
|
+
action,
|
|
45292
|
+
context || "",
|
|
45293
|
+
"",
|
|
45294
|
+
this.auth.privkey,
|
|
45295
|
+
brid
|
|
45296
|
+
);
|
|
44614
45297
|
const body = {
|
|
44615
45298
|
tool_call_id: logResult.toolCallId,
|
|
44616
45299
|
agent_pubkey: this.auth.pubkey,
|
|
@@ -44619,9 +45302,8 @@ var Atbash = class _Atbash {
|
|
|
44619
45302
|
};
|
|
44620
45303
|
if (signedJudgeAction) body.signed_judge_action = signedJudgeAction;
|
|
44621
45304
|
if (context) body.context = context;
|
|
44622
|
-
if (options.provider) body.provider = options.provider;
|
|
44623
45305
|
if (options.toolName) body.tool_name = options.toolName;
|
|
44624
|
-
if (options.
|
|
45306
|
+
if (options.toolArgsJson) body.tool_args_json = options.toolArgsJson;
|
|
44625
45307
|
if (options.resolved) body.resolved = options.resolved;
|
|
44626
45308
|
if (options.mode) body.mode = options.mode;
|
|
44627
45309
|
let resp;
|
|
@@ -44632,44 +45314,28 @@ var Atbash = class _Atbash {
|
|
|
44632
45314
|
}
|
|
44633
45315
|
if (!resp.ok) throw await this.httpError(resp);
|
|
44634
45316
|
const bodyBytes = Buffer.from(await resp.arrayBuffer());
|
|
44635
|
-
const verifyPubKey = options.verifyPubKey
|
|
45317
|
+
const verifyPubKey = this.effectiveVerifyKey(options.verifyPubKey);
|
|
44636
45318
|
if (verifyPubKey !== void 0) {
|
|
44637
|
-
|
|
44638
|
-
if (!sig) {
|
|
44639
|
-
throw new SignatureVerificationError(
|
|
44640
|
-
"missing X-Atbash-Signature header"
|
|
44641
|
-
);
|
|
44642
|
-
}
|
|
44643
|
-
let ok;
|
|
44644
|
-
try {
|
|
44645
|
-
ok = native.verifySignature(bodyBytes, sig, verifyPubKey);
|
|
44646
|
-
} catch (err) {
|
|
44647
|
-
throw new SignatureVerificationError(
|
|
44648
|
-
`signature verification threw: ${errorMessage(err)}`
|
|
44649
|
-
);
|
|
44650
|
-
}
|
|
44651
|
-
if (!ok) {
|
|
44652
|
-
throw new SignatureVerificationError(
|
|
44653
|
-
"signature does not verify against configured verifyPubKey"
|
|
44654
|
-
);
|
|
44655
|
-
}
|
|
45319
|
+
verifyResponseSignature(bodyBytes, resp, verifyPubKey);
|
|
44656
45320
|
}
|
|
44657
45321
|
const data = parseJson(bodyBytes);
|
|
44658
45322
|
const rawScore = data.score;
|
|
44659
45323
|
const score = typeof rawScore === "number" && Number.isInteger(rawScore) && rawScore >= 1 && rawScore <= 10 ? rawScore : void 0;
|
|
44660
45324
|
return {
|
|
44661
45325
|
verdict: normalizeVerdict(data.verdict),
|
|
44662
|
-
|
|
44663
|
-
|
|
44664
|
-
|
|
44665
|
-
|
|
44666
|
-
|
|
44667
|
-
|
|
45326
|
+
allow: this.executable(data),
|
|
45327
|
+
actionType: normalizeActionType(data.action_type),
|
|
45328
|
+
reason: wireText(data.reason),
|
|
45329
|
+
confidence: wireNumber(data.confidence),
|
|
45330
|
+
provider: wireText(data.provider),
|
|
45331
|
+
latencyMs: wireNumber(data.latency_ms),
|
|
45332
|
+
toolCallId: wireText(data.tool_call_id, logResult.toolCallId),
|
|
44668
45333
|
onChain: Boolean(data.on_chain),
|
|
44669
45334
|
enforced: Boolean(data.enforced),
|
|
44670
|
-
enforcementMode:
|
|
44671
|
-
status:
|
|
44672
|
-
score
|
|
45335
|
+
enforcementMode: wireText(data.enforcement_mode),
|
|
45336
|
+
status: wireText(data.status),
|
|
45337
|
+
score,
|
|
45338
|
+
refusal: explicitRefusal(data)
|
|
44673
45339
|
};
|
|
44674
45340
|
}
|
|
44675
45341
|
/* ── audit_tool_call (redact → judge → decision) ───────────────────────── */
|
|
@@ -44702,97 +45368,197 @@ var Atbash = class _Atbash {
|
|
|
44702
45368
|
}
|
|
44703
45369
|
try {
|
|
44704
45370
|
this.logger.info?.("[atbash] judge API called", { tool: toolName });
|
|
44705
|
-
const result = await
|
|
44706
|
-
|
|
44707
|
-
|
|
44708
|
-
|
|
44709
|
-
|
|
44710
|
-
|
|
44711
|
-
|
|
44712
|
-
|
|
44713
|
-
|
|
44714
|
-
|
|
44715
|
-
|
|
44716
|
-
|
|
44717
|
-
|
|
44718
|
-
|
|
44719
|
-
return {
|
|
44720
|
-
allow: true,
|
|
44721
|
-
verdict: "ALLOW",
|
|
44722
|
-
reason: result.reason || "audit tier \u2014 request logged on-chain, no AI enforcement",
|
|
44723
|
-
toolCallId: result.toolCallId
|
|
44724
|
-
};
|
|
44725
|
-
}
|
|
44726
|
-
const action = result.actionType;
|
|
44727
|
-
if (action === "block") {
|
|
45371
|
+
const result = await withDeadline(
|
|
45372
|
+
this.judgeAction(actionText, contextText, {
|
|
45373
|
+
toolName,
|
|
45374
|
+
toolArgsJson: argsJson,
|
|
45375
|
+
orgName: this.orgName,
|
|
45376
|
+
// Passed through unredacted — caller vouches for the contents.
|
|
45377
|
+
resolved: input.resolved
|
|
45378
|
+
}),
|
|
45379
|
+
this.decisionTimeoutMs
|
|
45380
|
+
);
|
|
45381
|
+
return this.decide(result);
|
|
45382
|
+
} catch (err) {
|
|
45383
|
+
if (err instanceof SignatureVerificationError) {
|
|
45384
|
+
this.failJudge(errorMessage(err), err);
|
|
44728
45385
|
return {
|
|
44729
45386
|
allow: false,
|
|
44730
|
-
verdict: "
|
|
44731
|
-
reason:
|
|
44732
|
-
toolCallId: result.toolCallId
|
|
45387
|
+
verdict: "ERROR",
|
|
45388
|
+
reason: `The judge's reply failed its signature check (${errorMessage(err)}), so it was not trusted.`
|
|
44733
45389
|
};
|
|
44734
45390
|
}
|
|
44735
|
-
|
|
44736
|
-
|
|
44737
|
-
|
|
44738
|
-
|
|
44739
|
-
|
|
44740
|
-
|
|
44741
|
-
|
|
45391
|
+
return this.failJudge(errorMessage(err), err);
|
|
45392
|
+
}
|
|
45393
|
+
}
|
|
45394
|
+
/**
|
|
45395
|
+
* The verify key for one call (R4, governor tier-2 review). A per-call key
|
|
45396
|
+
* may only narrow what the client accepts: on a client pinned to a judge
|
|
45397
|
+
* key it must be that same key, never a replacement; on an unpinned client
|
|
45398
|
+
* it adds the check.
|
|
45399
|
+
*/
|
|
45400
|
+
effectiveVerifyKey(perCall) {
|
|
45401
|
+
if (perCall === void 0) return this.verifyPubKey;
|
|
45402
|
+
const key3 = perCall.trim().toLowerCase();
|
|
45403
|
+
if (this.verifyPubKey !== void 0 && key3 !== this.verifyPubKey) {
|
|
45404
|
+
throw new SignatureVerificationError(
|
|
45405
|
+
"a per-call verifyPubKey cannot replace the judge key this client is pinned to"
|
|
45406
|
+
);
|
|
45407
|
+
}
|
|
45408
|
+
return key3;
|
|
45409
|
+
}
|
|
45410
|
+
/**
|
|
45411
|
+
* Collapse a judge result into a {@link Decision}. The most restrictive
|
|
45412
|
+
* signal wins (security review 2026-09-30, H1): `action_type`, `verdict`
|
|
45413
|
+
* and the canonical `allow` are each able to deny, and only a result where
|
|
45414
|
+
* all three agree may execute. A present `allow` / `decision.allow` that is
|
|
45415
|
+
* not exactly `true` is the judge declining to grant permission, so it
|
|
45416
|
+
* denies even under `failClosed: false` — that option relaxes *errors*, it
|
|
45417
|
+
* never overrides a refusal.
|
|
45418
|
+
*/
|
|
45419
|
+
decide(result) {
|
|
45420
|
+
const toolCallId = result.toolCallId;
|
|
45421
|
+
const deny = (verdict, reason) => ({
|
|
45422
|
+
allow: false,
|
|
45423
|
+
verdict,
|
|
45424
|
+
reason,
|
|
45425
|
+
toolCallId
|
|
45426
|
+
});
|
|
45427
|
+
const notGranted = "the judge response did not grant permission";
|
|
45428
|
+
const held = deny("HOLD", result.reason || "held for human confirmation");
|
|
45429
|
+
const blocked = deny("BLOCK", result.reason || notGranted);
|
|
45430
|
+
if (result.refusal === "BLOCK") return blocked;
|
|
45431
|
+
if (result.verdict === "No verdict") {
|
|
45432
|
+
if (result.actionType === "block") {
|
|
45433
|
+
return blocked;
|
|
45434
|
+
}
|
|
45435
|
+
if (result.actionType === "hold_for_user_confirm") {
|
|
45436
|
+
return held;
|
|
45437
|
+
}
|
|
45438
|
+
if (result.refusal === "HOLD") return held;
|
|
45439
|
+
if (result.status !== "logged") {
|
|
45440
|
+
return this.failJudge(
|
|
45441
|
+
`judge returned no verdict without an audit-tier marker (status: ${result.status || "absent"})`,
|
|
45442
|
+
void 0,
|
|
45443
|
+
toolCallId
|
|
45444
|
+
);
|
|
44742
45445
|
}
|
|
44743
|
-
if (
|
|
44744
|
-
|
|
44745
|
-
|
|
44746
|
-
|
|
44747
|
-
|
|
44748
|
-
reason: result.reason,
|
|
44749
|
-
toolCallId: result.toolCallId
|
|
44750
|
-
};
|
|
44751
|
-
}
|
|
44752
|
-
if (result.verdict === "BLOCK") {
|
|
44753
|
-
return {
|
|
44754
|
-
allow: false,
|
|
44755
|
-
verdict: "BLOCK",
|
|
44756
|
-
reason: result.reason,
|
|
44757
|
-
toolCallId: result.toolCallId
|
|
44758
|
-
};
|
|
44759
|
-
}
|
|
45446
|
+
if (this.requireEnforcement) {
|
|
45447
|
+
this.logger.warn?.(
|
|
45448
|
+
"[atbash] judge did not enforce this action (audit tier) and requireEnforcement is on: denied",
|
|
45449
|
+
{ toolCallId }
|
|
45450
|
+
);
|
|
44760
45451
|
return {
|
|
44761
|
-
allow:
|
|
44762
|
-
verdict: "
|
|
44763
|
-
reason:
|
|
44764
|
-
toolCallId
|
|
45452
|
+
allow: false,
|
|
45453
|
+
verdict: "ERROR",
|
|
45454
|
+
reason: "Atbash logged this action but did not check it (audit-tier plan), and this client requires a checked decision. Upgrade the plan, or set requireEnforcement: false for log-only mode.",
|
|
45455
|
+
toolCallId
|
|
44765
45456
|
};
|
|
44766
45457
|
}
|
|
44767
|
-
return
|
|
44768
|
-
|
|
44769
|
-
|
|
44770
|
-
|
|
44771
|
-
|
|
44772
|
-
|
|
44773
|
-
|
|
44774
|
-
|
|
45458
|
+
if (result.allow !== true) return deny("BLOCK", notGranted);
|
|
45459
|
+
return {
|
|
45460
|
+
allow: true,
|
|
45461
|
+
verdict: "ALLOW",
|
|
45462
|
+
reason: result.reason || "audit tier \u2014 request logged on-chain, no AI enforcement",
|
|
45463
|
+
toolCallId
|
|
45464
|
+
};
|
|
45465
|
+
}
|
|
45466
|
+
const action = result.actionType;
|
|
45467
|
+
if (action === "block") {
|
|
45468
|
+
return deny("BLOCK", result.reason || "Blocked by your organisation's Atbash policy.");
|
|
44775
45469
|
}
|
|
45470
|
+
if (action === "hold_for_user_confirm") {
|
|
45471
|
+
return held;
|
|
45472
|
+
}
|
|
45473
|
+
if (result.refusal === "HOLD") return held;
|
|
45474
|
+
if (action === "allow") {
|
|
45475
|
+
if (result.verdict === "HOLD") return held;
|
|
45476
|
+
if (result.verdict === "BLOCK") return blocked;
|
|
45477
|
+
if (result.allow !== true) return deny("BLOCK", notGranted);
|
|
45478
|
+
return {
|
|
45479
|
+
allow: true,
|
|
45480
|
+
verdict: "ALLOW",
|
|
45481
|
+
reason: result.reason,
|
|
45482
|
+
toolCallId
|
|
45483
|
+
};
|
|
45484
|
+
}
|
|
45485
|
+
return this.failJudge(
|
|
45486
|
+
"unrecognized action_type from judge",
|
|
45487
|
+
void 0,
|
|
45488
|
+
toolCallId
|
|
45489
|
+
);
|
|
45490
|
+
}
|
|
45491
|
+
/**
|
|
45492
|
+
* One exit for every judge failure.
|
|
45493
|
+
*
|
|
45494
|
+
* Status and reason go in the *message*, not only in the meta object: hosts
|
|
45495
|
+
* print the message and drop the meta, which is why this read as a bare
|
|
45496
|
+
* "judge API failed" while the judge was answering with a precise reason.
|
|
45497
|
+
* The response body follows only under `debug`, since it can echo the action.
|
|
45498
|
+
*/
|
|
45499
|
+
failJudge(reason, cause, toolCallId) {
|
|
45500
|
+
const api2 = cause instanceof AtbashAPIError ? cause : null;
|
|
45501
|
+
const userReason = userFacingReason(reason, api2);
|
|
45502
|
+
const status = api2 ? ` status=${api2.status || "no-response"}` : "";
|
|
45503
|
+
const detail = this.debug ? ` detail=${truncate(reason, 500)}` : "";
|
|
45504
|
+
const body = this.debug && api2?.body ? ` body=${truncate(api2.body, 500)}` : "";
|
|
45505
|
+
this.logger.warn?.(
|
|
45506
|
+
`[atbash] judge API failed \u2014${status} reason=${truncate(userReason, 300)}${detail}${body}`,
|
|
45507
|
+
{
|
|
45508
|
+
reason: userReason,
|
|
45509
|
+
...api2 ? { status: api2.status } : {},
|
|
45510
|
+
...this.debug && api2 ? { body: api2.body, detail: reason } : {},
|
|
45511
|
+
endpoint: this.endpoint,
|
|
45512
|
+
...toolCallId ? { toolCallId } : {}
|
|
45513
|
+
}
|
|
45514
|
+
);
|
|
45515
|
+
return this.fail(userReason, toolCallId);
|
|
45516
|
+
}
|
|
45517
|
+
/**
|
|
45518
|
+
* The canonical permission for a response body under this client's
|
|
45519
|
+
* settings: {@link canonicalAllow}, minus the audit tier when
|
|
45520
|
+
* `requireEnforcement` is on. Never more permissive than `auditToolCall`.
|
|
45521
|
+
*/
|
|
45522
|
+
executable(data) {
|
|
45523
|
+
if (!canonicalAllow(data)) return false;
|
|
45524
|
+
return !(this.requireEnforcement && isAuditTierBody(data));
|
|
44776
45525
|
}
|
|
44777
45526
|
fail(reason, toolCallId) {
|
|
44778
45527
|
return { allow: !this.failClosed, verdict: "ERROR", reason, toolCallId };
|
|
44779
45528
|
}
|
|
44780
45529
|
/* ── judgment status ───────────────────────────────────────────────────── */
|
|
44781
|
-
|
|
45530
|
+
/**
|
|
45531
|
+
* Return the current status of a previously submitted judgment.
|
|
45532
|
+
*
|
|
45533
|
+
* `chainOpts` names which chain the judgment was signed against. The
|
|
45534
|
+
* server's GET /api/v1/judge routes to that chain when the SDK sends
|
|
45535
|
+
* a `brid` query param; without it, the server falls back to public.
|
|
45536
|
+
* Callers on the private chain must pass a `chainOpts` (or configure
|
|
45537
|
+
* the client on the private chain) — otherwise polling a POSTed
|
|
45538
|
+
* judgment on the private chain 404s at the server.
|
|
45539
|
+
*/
|
|
45540
|
+
async getJudgmentStatus(judgmentId, agentPubkey, chainOpts) {
|
|
44782
45541
|
const pk = agentPubkey ?? this.auth.pubkey;
|
|
45542
|
+
const brid = this.bridFromChainOpts(chainOpts);
|
|
44783
45543
|
return this.track("getJudgmentStatus", pk, async () => {
|
|
44784
45544
|
const resp = await this.http.get(
|
|
44785
45545
|
"/api/v1/judge",
|
|
44786
|
-
{ tool_call_id: judgmentId, agent_pubkey: pk },
|
|
44787
|
-
this.authHeaders()
|
|
45546
|
+
{ tool_call_id: judgmentId, agent_pubkey: pk, brid },
|
|
45547
|
+
this.authHeaders(brid)
|
|
44788
45548
|
);
|
|
44789
45549
|
await this.raiseIfError(resp);
|
|
44790
|
-
const
|
|
45550
|
+
const bytes = Buffer.from(await resp.arrayBuffer());
|
|
45551
|
+
if (this.verifyPubKey !== void 0) {
|
|
45552
|
+
verifyResponseSignature(bytes, resp, this.verifyPubKey);
|
|
45553
|
+
}
|
|
45554
|
+
const parsed = tryParseJson(bytes.toString("utf-8"));
|
|
45555
|
+
const data = isRecord2(parsed) ? parsed : {};
|
|
44791
45556
|
return {
|
|
44792
45557
|
status: normalizeStatus(data.status),
|
|
44793
45558
|
verdict: normalizeVerdict(data.verdict),
|
|
44794
|
-
|
|
44795
|
-
|
|
45559
|
+
allow: this.executable(data),
|
|
45560
|
+
reason: wireText(data.reason),
|
|
45561
|
+
judgmentId: wireText(data.judgmentId, judgmentId),
|
|
44796
45562
|
onChain: optBool(data.onChain),
|
|
44797
45563
|
cached: optBool(data.cached),
|
|
44798
45564
|
responseTimeMs: optNumber(data.responseTimeMs)
|
|
@@ -44804,49 +45570,65 @@ var Atbash = class _Atbash {
|
|
|
44804
45570
|
return this.track(
|
|
44805
45571
|
"getToolCalls",
|
|
44806
45572
|
void 0,
|
|
44807
|
-
() => this.riskEngineRecords(
|
|
45573
|
+
async () => this.riskEngineRecords(
|
|
45574
|
+
"tool-calls",
|
|
45575
|
+
{ limit: maxCount },
|
|
45576
|
+
await this.defaultOrgBrid()
|
|
45577
|
+
)
|
|
44808
45578
|
);
|
|
44809
45579
|
}
|
|
44810
|
-
getOrgToolCalls(orgName, maxCount) {
|
|
44811
|
-
return this.track(
|
|
44812
|
-
|
|
44813
|
-
|
|
44814
|
-
|
|
44815
|
-
org: orgName,
|
|
44816
|
-
|
|
44817
|
-
|
|
44818
|
-
);
|
|
45580
|
+
async getOrgToolCalls(orgName, maxCount) {
|
|
45581
|
+
return this.track("getOrgToolCalls", void 0, async () => {
|
|
45582
|
+
const brid = await this.bridForOrg(orgName);
|
|
45583
|
+
return this.riskEngineRecords(
|
|
45584
|
+
"org-tool-calls",
|
|
45585
|
+
{ org: orgName, limit: maxCount },
|
|
45586
|
+
brid
|
|
45587
|
+
);
|
|
45588
|
+
});
|
|
44819
45589
|
}
|
|
44820
45590
|
getAgentToolCalls(agentPubkey, maxCount) {
|
|
44821
45591
|
return this.track(
|
|
44822
45592
|
"getAgentToolCalls",
|
|
44823
45593
|
agentPubkey,
|
|
44824
|
-
() => this.riskEngineRecords(
|
|
44825
|
-
agent
|
|
44826
|
-
limit: maxCount
|
|
44827
|
-
|
|
45594
|
+
async () => this.riskEngineRecords(
|
|
45595
|
+
"agent-tool-calls",
|
|
45596
|
+
{ agent: agentPubkey, limit: maxCount },
|
|
45597
|
+
await this.defaultOrgBrid()
|
|
45598
|
+
)
|
|
44828
45599
|
);
|
|
44829
45600
|
}
|
|
44830
45601
|
async getToolCallCount() {
|
|
44831
45602
|
return this.track("getToolCallCount", void 0, async () => {
|
|
44832
|
-
const raw2 = await this.riskEngineGet(
|
|
45603
|
+
const raw2 = await this.riskEngineGet(
|
|
45604
|
+
"tool-call-count",
|
|
45605
|
+
{},
|
|
45606
|
+
await this.defaultOrgBrid()
|
|
45607
|
+
);
|
|
44833
45608
|
const n = Number(raw2);
|
|
44834
45609
|
return Number.isFinite(n) ? n : 0;
|
|
44835
45610
|
});
|
|
44836
45611
|
}
|
|
44837
45612
|
async getToolCallFull(toolCallId) {
|
|
44838
45613
|
return this.track("getToolCallFull", void 0, async () => {
|
|
44839
|
-
const raw2 = await this.riskEngineGet(
|
|
44840
|
-
|
|
44841
|
-
|
|
44842
|
-
|
|
45614
|
+
const raw2 = await this.riskEngineGet(
|
|
45615
|
+
"tool-call-full",
|
|
45616
|
+
{ tool_call_id: toolCallId },
|
|
45617
|
+
await this.defaultOrgBrid()
|
|
45618
|
+
);
|
|
45619
|
+
if (!isRecord2(raw2)) return null;
|
|
44843
45620
|
return toToolCallFull(raw2);
|
|
44844
45621
|
});
|
|
44845
45622
|
}
|
|
44846
45623
|
async getOrgTierInfo(orgName) {
|
|
44847
45624
|
return this.track("getOrgTierInfo", void 0, async () => {
|
|
44848
|
-
const
|
|
44849
|
-
|
|
45625
|
+
const brid = await this.bridForOrg(orgName);
|
|
45626
|
+
const raw2 = await this.riskEngineGet(
|
|
45627
|
+
"org-tier-info",
|
|
45628
|
+
{ org: orgName },
|
|
45629
|
+
brid
|
|
45630
|
+
);
|
|
45631
|
+
if (!isRecord2(raw2)) return null;
|
|
44850
45632
|
return {
|
|
44851
45633
|
orgName: String(raw2.org_name ?? ""),
|
|
44852
45634
|
tier: String(raw2.tier ?? ""),
|
|
@@ -44857,20 +45639,24 @@ var Atbash = class _Atbash {
|
|
|
44857
45639
|
}
|
|
44858
45640
|
async getPendingHeldActions(orgName, maxCount) {
|
|
44859
45641
|
return this.track("getPendingHeldActions", void 0, async () => {
|
|
44860
|
-
const
|
|
44861
|
-
|
|
44862
|
-
|
|
44863
|
-
|
|
45642
|
+
const brid = await this.bridForOrg(orgName);
|
|
45643
|
+
const raw2 = await this.riskEngineGet(
|
|
45644
|
+
"pending-held-actions",
|
|
45645
|
+
{ org: orgName, limit: maxCount },
|
|
45646
|
+
brid
|
|
45647
|
+
);
|
|
44864
45648
|
if (!Array.isArray(raw2)) return [];
|
|
44865
45649
|
return raw2.map((item) => toHeldAction(item));
|
|
44866
45650
|
});
|
|
44867
45651
|
}
|
|
44868
45652
|
async getHeldActionReviews(orgName, maxCount) {
|
|
44869
45653
|
return this.track("getHeldActionReviews", void 0, async () => {
|
|
44870
|
-
const
|
|
44871
|
-
|
|
44872
|
-
|
|
44873
|
-
|
|
45654
|
+
const brid = await this.bridForOrg(orgName);
|
|
45655
|
+
const raw2 = await this.riskEngineGet(
|
|
45656
|
+
"held-action-reviews",
|
|
45657
|
+
{ org: orgName, limit: maxCount },
|
|
45658
|
+
brid
|
|
45659
|
+
);
|
|
44874
45660
|
if (!Array.isArray(raw2)) return [];
|
|
44875
45661
|
return raw2.map(
|
|
44876
45662
|
(item) => toHeldActionReview(item)
|
|
@@ -44878,19 +45664,29 @@ var Atbash = class _Atbash {
|
|
|
44878
45664
|
});
|
|
44879
45665
|
}
|
|
44880
45666
|
/* ── risk-engine batched (action-dispatched POST) ──────────────────────── */
|
|
44881
|
-
getAgentDetail(agentPubkey) {
|
|
44882
|
-
return this.track(
|
|
44883
|
-
|
|
44884
|
-
|
|
44885
|
-
|
|
44886
|
-
|
|
45667
|
+
async getAgentDetail(agentPubkey, options = {}) {
|
|
45668
|
+
return this.track("getAgentDetail", agentPubkey, async () => {
|
|
45669
|
+
const network = await this.resolveAgentLookupNetwork(options);
|
|
45670
|
+
const brid = network ? this.bridFromChainOpts({ network }) : void 0;
|
|
45671
|
+
return this.riskEnginePost(
|
|
45672
|
+
{ action: "agent-detail-batch", agent: agentPubkey },
|
|
45673
|
+
network,
|
|
45674
|
+
brid
|
|
45675
|
+
);
|
|
45676
|
+
});
|
|
44887
45677
|
}
|
|
44888
|
-
async getAgentPolicy(agentPubkey) {
|
|
45678
|
+
async getAgentPolicy(agentPubkey, options = {}) {
|
|
44889
45679
|
return this.track("getAgentPolicy", agentPubkey, async () => {
|
|
44890
|
-
const
|
|
44891
|
-
|
|
44892
|
-
|
|
44893
|
-
|
|
45680
|
+
const network = await this.resolveAgentLookupNetwork(options);
|
|
45681
|
+
const brid = network ? this.bridFromChainOpts({ network }) : void 0;
|
|
45682
|
+
const raw2 = await this.riskEnginePost(
|
|
45683
|
+
{
|
|
45684
|
+
action: "agent-policy-batch",
|
|
45685
|
+
agent: agentPubkey
|
|
45686
|
+
},
|
|
45687
|
+
network,
|
|
45688
|
+
brid
|
|
45689
|
+
);
|
|
44894
45690
|
return {
|
|
44895
45691
|
policy: String(raw2.policy ?? ""),
|
|
44896
45692
|
isJailed: Boolean(raw2.is_jailed),
|
|
@@ -44905,11 +45701,11 @@ var Atbash = class _Atbash {
|
|
|
44905
45701
|
const resp = await this.http.get(
|
|
44906
45702
|
"/api/insurance",
|
|
44907
45703
|
{ action: "safety-stats" },
|
|
44908
|
-
this.authHeaders()
|
|
45704
|
+
this.authHeaders(await this.defaultOrgBrid())
|
|
44909
45705
|
);
|
|
44910
45706
|
await this.raiseIfError(resp);
|
|
44911
45707
|
const data = await this.json(resp) ?? {};
|
|
44912
|
-
if (
|
|
45708
|
+
if (isRecord2(data.data)) return data.data;
|
|
44913
45709
|
return data;
|
|
44914
45710
|
});
|
|
44915
45711
|
}
|
|
@@ -44923,8 +45719,9 @@ var Atbash = class _Atbash {
|
|
|
44923
45719
|
return this.track("getOrgSubscription", void 0, async () => {
|
|
44924
45720
|
const params = { org: orgName };
|
|
44925
45721
|
if (network) params.network = network;
|
|
44926
|
-
const
|
|
44927
|
-
|
|
45722
|
+
const brid = network ? this.bridFromChainOpts({ network }) : void 0;
|
|
45723
|
+
const raw2 = await this.riskEngineGet("org-subscription", params, brid);
|
|
45724
|
+
if (!isRecord2(raw2)) return null;
|
|
44928
45725
|
return coerceOrgSubscription(raw2, orgName);
|
|
44929
45726
|
});
|
|
44930
45727
|
}
|
|
@@ -44936,21 +45733,22 @@ var Atbash = class _Atbash {
|
|
|
44936
45733
|
* entry (caller falls back to per-chain subscription resolution).
|
|
44937
45734
|
*/
|
|
44938
45735
|
async getActiveNetworkForOrg(orgName) {
|
|
45736
|
+
let resp;
|
|
44939
45737
|
try {
|
|
44940
|
-
|
|
45738
|
+
resp = await this.http.get(
|
|
44941
45739
|
"/api/org-network",
|
|
44942
|
-
{ org: orgName },
|
|
45740
|
+
{ org: orgName.trim() },
|
|
44943
45741
|
this.authHeaders()
|
|
44944
45742
|
);
|
|
44945
|
-
|
|
44946
|
-
|
|
44947
|
-
if (data?.network === "public" || data?.network === "private") {
|
|
44948
|
-
return data.network;
|
|
44949
|
-
}
|
|
44950
|
-
return null;
|
|
44951
|
-
} catch {
|
|
44952
|
-
return null;
|
|
45743
|
+
} catch (err) {
|
|
45744
|
+
throw this.transportError(err);
|
|
44953
45745
|
}
|
|
45746
|
+
if (resp.status !== 200) throw await this.httpError(resp);
|
|
45747
|
+
const data = await this.json(resp);
|
|
45748
|
+
if (data?.network === "public" || data?.network === "private") {
|
|
45749
|
+
return data.network;
|
|
45750
|
+
}
|
|
45751
|
+
return null;
|
|
44954
45752
|
}
|
|
44955
45753
|
/**
|
|
44956
45754
|
* Resolve which chain an org's actions should run against. Cached
|
|
@@ -44959,13 +45757,19 @@ var Atbash = class _Atbash {
|
|
|
44959
45757
|
* 2. Per-chain subscription fallback — public + private records
|
|
44960
45758
|
* are fetched in parallel, with `is_private_blockchain` and
|
|
44961
45759
|
* `assigned_at` reconciling mixed states.
|
|
44962
|
-
*
|
|
45760
|
+
* A lookup that names exactly one chain wins outright. Where it names
|
|
45761
|
+
* neither (a brand-new org) or cannot choose between them, the client's
|
|
45762
|
+
* configured default decides.
|
|
44963
45763
|
*/
|
|
44964
45764
|
async resolveChainForOrg(orgName) {
|
|
44965
|
-
const
|
|
45765
|
+
const name2 = orgName.trim();
|
|
45766
|
+
if (this._explicitChain) return this._defaultChain;
|
|
45767
|
+
const forced = this.forcedNetwork();
|
|
45768
|
+
if (forced) return chainForNetwork(forced);
|
|
45769
|
+
const cached = this._chainCache.get(name2);
|
|
44966
45770
|
if (cached) return cached;
|
|
44967
|
-
const mapNetwork = await this.getActiveNetworkForOrg(
|
|
44968
|
-
return this.resolveChainFromMap(
|
|
45771
|
+
const mapNetwork = await this.getActiveNetworkForOrg(name2);
|
|
45772
|
+
return this.resolveChainFromMap(name2, mapNetwork);
|
|
44969
45773
|
}
|
|
44970
45774
|
/**
|
|
44971
45775
|
* Resolve a chain given an already-fetched `org_networks` map result.
|
|
@@ -44981,37 +45785,50 @@ var Atbash = class _Atbash {
|
|
|
44981
45785
|
this._chainCache.set(orgName, chain);
|
|
44982
45786
|
return chain;
|
|
44983
45787
|
}
|
|
44984
|
-
|
|
44985
|
-
|
|
44986
|
-
|
|
44987
|
-
|
|
44988
|
-
|
|
44989
|
-
|
|
44990
|
-
|
|
44991
|
-
|
|
44992
|
-
|
|
44993
|
-
|
|
44994
|
-
|
|
44995
|
-
|
|
44996
|
-
|
|
44997
|
-
|
|
44998
|
-
|
|
44999
|
-
|
|
45000
|
-
|
|
45001
|
-
|
|
45002
|
-
|
|
45003
|
-
this._chainCache.set(orgName, PRIVATE_CHAIN);
|
|
45004
|
-
return PRIVATE_CHAIN;
|
|
45005
|
-
}
|
|
45006
|
-
} catch {
|
|
45788
|
+
const [pubRes, privRes] = await Promise.allSettled([
|
|
45789
|
+
this.getOrgSubscription(orgName, "public"),
|
|
45790
|
+
this.getOrgSubscription(orgName, "private")
|
|
45791
|
+
]);
|
|
45792
|
+
const pubSub = pubRes.status === "fulfilled" ? pubRes.value : null;
|
|
45793
|
+
const privSub = privRes.status === "fulfilled" ? privRes.value : null;
|
|
45794
|
+
const failure = pubRes.status === "rejected" ? pubRes.reason : privRes.status === "rejected" ? privRes.reason : null;
|
|
45795
|
+
if (pubSub?.is_private_blockchain) {
|
|
45796
|
+
this._chainCache.set(orgName, PRIVATE_CHAIN);
|
|
45797
|
+
return PRIVATE_CHAIN;
|
|
45798
|
+
}
|
|
45799
|
+
if (pubSub && privSub) {
|
|
45800
|
+
const chain = privSub.assigned_at === pubSub.assigned_at ? this._defaultChain : privSub.assigned_at > pubSub.assigned_at ? PRIVATE_CHAIN : PUBLIC_CHAIN;
|
|
45801
|
+
this._chainCache.set(orgName, chain);
|
|
45802
|
+
return chain;
|
|
45803
|
+
}
|
|
45804
|
+
if (pubSub) {
|
|
45805
|
+
this._chainCache.set(orgName, PUBLIC_CHAIN);
|
|
45806
|
+
return PUBLIC_CHAIN;
|
|
45007
45807
|
}
|
|
45008
|
-
|
|
45009
|
-
|
|
45808
|
+
if (privSub?.is_private_blockchain) {
|
|
45809
|
+
this._chainCache.set(orgName, PRIVATE_CHAIN);
|
|
45810
|
+
return PRIVATE_CHAIN;
|
|
45811
|
+
}
|
|
45812
|
+
if (failure) {
|
|
45813
|
+
const detail = failure instanceof Error ? failure.message : String(failure);
|
|
45814
|
+
throw new AtbashAPIError(
|
|
45815
|
+
failure instanceof AtbashAPIError ? failure.status : 0,
|
|
45816
|
+
`could not resolve the chain for org "${orgName}": ${detail}`,
|
|
45817
|
+
"",
|
|
45818
|
+
this.endpoint
|
|
45819
|
+
);
|
|
45820
|
+
}
|
|
45821
|
+
this._chainCache.set(orgName, this._defaultChain);
|
|
45822
|
+
return this._defaultChain;
|
|
45010
45823
|
}
|
|
45011
45824
|
/** Drop any cached chain resolutions. Useful in tests. */
|
|
45012
45825
|
clearChainCache() {
|
|
45013
45826
|
this._chainCache.clear();
|
|
45014
45827
|
}
|
|
45828
|
+
/** Drop the short-TTL `/api/ai/exists` cache. Useful in tests. */
|
|
45829
|
+
clearAgentExistsCache() {
|
|
45830
|
+
this._agentExistsCache = null;
|
|
45831
|
+
}
|
|
45015
45832
|
/* ── internals ─────────────────────────────────────────────────────────── */
|
|
45016
45833
|
/**
|
|
45017
45834
|
* Wrap an SDK method body in telemetry — records the call at start
|
|
@@ -45025,10 +45842,28 @@ var Atbash = class _Atbash {
|
|
|
45025
45842
|
recordCall(name2, void 0, agentPubkey);
|
|
45026
45843
|
try {
|
|
45027
45844
|
const result = await fn();
|
|
45028
|
-
|
|
45845
|
+
const durationMs = performance.now() - start;
|
|
45846
|
+
recordDuration(name2, durationMs, "success");
|
|
45847
|
+
recordEvent({
|
|
45848
|
+
functionName: name2,
|
|
45849
|
+
durationMs,
|
|
45850
|
+
status: "success",
|
|
45851
|
+
agentPubkey,
|
|
45852
|
+
chain: this.blockchainRid
|
|
45853
|
+
});
|
|
45029
45854
|
return result;
|
|
45030
45855
|
} catch (err) {
|
|
45031
|
-
|
|
45856
|
+
const durationMs = performance.now() - start;
|
|
45857
|
+
recordDuration(name2, durationMs, "error");
|
|
45858
|
+
recordEvent({
|
|
45859
|
+
functionName: name2,
|
|
45860
|
+
durationMs,
|
|
45861
|
+
status: "error",
|
|
45862
|
+
agentPubkey,
|
|
45863
|
+
chain: this.blockchainRid,
|
|
45864
|
+
errorClass: err instanceof Error ? err.constructor.name : typeof err,
|
|
45865
|
+
...errorDetail(err)
|
|
45866
|
+
});
|
|
45032
45867
|
throw err;
|
|
45033
45868
|
}
|
|
45034
45869
|
}
|
|
@@ -45043,6 +45878,21 @@ var Atbash = class _Atbash {
|
|
|
45043
45878
|
if (chainOpts?.network === "public") return PUBLIC_CHAIN.blockchainRid;
|
|
45044
45879
|
return this.blockchainRid;
|
|
45045
45880
|
}
|
|
45881
|
+
/**
|
|
45882
|
+
* Resolve the dashboard chain used by agent metadata/policy reads.
|
|
45883
|
+
* Explicit per-call network overrides win; otherwise use the supplied org
|
|
45884
|
+
* or the client's configured default org. A custom BRID is intentionally
|
|
45885
|
+
* left untouched because it cannot be represented by the dashboard's
|
|
45886
|
+
* public/private query selector.
|
|
45887
|
+
*/
|
|
45888
|
+
async resolveAgentLookupNetwork(options) {
|
|
45889
|
+
if (options.chainOpts?.network) return options.chainOpts.network;
|
|
45890
|
+
if (options.chainOpts?.blockchainRid) return void 0;
|
|
45891
|
+
if (this._explicitChain) return this._defaultChain.network;
|
|
45892
|
+
const orgName = options.orgName ?? this.orgName;
|
|
45893
|
+
if (!orgName) return void 0;
|
|
45894
|
+
return (await this.resolveChainForOrg(orgName)).network;
|
|
45895
|
+
}
|
|
45046
45896
|
/**
|
|
45047
45897
|
* Get-or-create a Bearer token for dashboard reads. The token is a
|
|
45048
45898
|
* signed `log_tool_call` op (locally signed, never submitted) — the
|
|
@@ -45050,34 +45900,19 @@ var Atbash = class _Atbash {
|
|
|
45050
45900
|
* for 4 minutes; refreshed after that so a long-lived client never
|
|
45051
45901
|
* trips the server's replay window.
|
|
45052
45902
|
*/
|
|
45053
|
-
getAuthBearer() {
|
|
45054
|
-
|
|
45055
|
-
if (this._authBearer && now - this._authBearer.issuedAt < 4 * 60 * 1e3) {
|
|
45056
|
-
return this._authBearer.hex;
|
|
45057
|
-
}
|
|
45058
|
-
const nonce = `auth-${now.toString(36)}-${randomHex(4)}`;
|
|
45059
|
-
const hex = native.signLogToolCall(
|
|
45060
|
-
nonce,
|
|
45061
|
-
`auth:${now}`,
|
|
45062
|
-
"",
|
|
45063
|
-
"auth-bearer",
|
|
45064
|
-
"",
|
|
45065
|
-
this.auth.privkey,
|
|
45066
|
-
this.blockchainRid
|
|
45067
|
-
);
|
|
45068
|
-
this._authBearer = { hex, issuedAt: now };
|
|
45069
|
-
return hex;
|
|
45903
|
+
getAuthBearer(brid) {
|
|
45904
|
+
return agentAuthBearer(this.auth, brid ?? this.blockchainRid);
|
|
45070
45905
|
}
|
|
45071
|
-
authHeaders() {
|
|
45072
|
-
return
|
|
45906
|
+
authHeaders(brid) {
|
|
45907
|
+
return agentAuthHeaders(this.auth, brid ?? this.blockchainRid);
|
|
45073
45908
|
}
|
|
45074
|
-
async riskEngineGet(action, params) {
|
|
45909
|
+
async riskEngineGet(action, params, brid) {
|
|
45075
45910
|
let resp;
|
|
45076
45911
|
try {
|
|
45077
45912
|
resp = await this.http.get(
|
|
45078
45913
|
"/api/risk-engine",
|
|
45079
45914
|
{ action, ...params },
|
|
45080
|
-
this.authHeaders()
|
|
45915
|
+
this.authHeaders(brid)
|
|
45081
45916
|
);
|
|
45082
45917
|
} catch (err) {
|
|
45083
45918
|
throw this.transportError(err);
|
|
@@ -45085,22 +45920,60 @@ var Atbash = class _Atbash {
|
|
|
45085
45920
|
if (resp.status !== 200) throw await this.httpError(resp);
|
|
45086
45921
|
return this.json(resp);
|
|
45087
45922
|
}
|
|
45088
|
-
async riskEnginePost(body) {
|
|
45923
|
+
async riskEnginePost(body, network, brid) {
|
|
45089
45924
|
let resp;
|
|
45090
45925
|
try {
|
|
45091
|
-
|
|
45926
|
+
const path3 = network ? `/api/risk-engine?network=${encodeURIComponent(network)}` : "/api/risk-engine";
|
|
45927
|
+
resp = await this.http.post(path3, body, this.authHeaders(brid));
|
|
45092
45928
|
} catch (err) {
|
|
45093
45929
|
throw this.transportError(err);
|
|
45094
45930
|
}
|
|
45095
45931
|
if (resp.status !== 200) throw await this.httpError(resp);
|
|
45096
45932
|
const data = await this.json(resp);
|
|
45097
|
-
return
|
|
45933
|
+
return isRecord2(data) ? data : {};
|
|
45098
45934
|
}
|
|
45099
|
-
async riskEngineRecords(action, params) {
|
|
45100
|
-
const raw2 = await this.riskEngineGet(action, params);
|
|
45935
|
+
async riskEngineRecords(action, params, brid) {
|
|
45936
|
+
const raw2 = await this.riskEngineGet(action, params, brid);
|
|
45101
45937
|
if (!Array.isArray(raw2)) return [];
|
|
45102
45938
|
return raw2.map((item) => toToolCallRecord(item));
|
|
45103
45939
|
}
|
|
45940
|
+
/**
|
|
45941
|
+
* BRID for an org — one round-trip to the map, honoring the client's chain
|
|
45942
|
+
* cache. A "brand-new org" (nothing anywhere names its chain) is not an
|
|
45943
|
+
* error — `resolveChainForOrg` returns the client default for that case and
|
|
45944
|
+
* this helper returns its BRID. A transport failure or non-200 from
|
|
45945
|
+
* `/api/org-network` IS an error and propagates: the caller cannot fall
|
|
45946
|
+
* back to the default chain on outage, because with multi-chain live that
|
|
45947
|
+
* silently reads from the wrong chain. Matches the Python binding's
|
|
45948
|
+
* `_brid_for_org` semantics.
|
|
45949
|
+
*/
|
|
45950
|
+
async bridForOrg(orgName) {
|
|
45951
|
+
return (await this.resolveChainForOrg(orgName)).blockchainRid;
|
|
45952
|
+
}
|
|
45953
|
+
/**
|
|
45954
|
+
* BRID for the client's configured default org, if it has one.
|
|
45955
|
+
*
|
|
45956
|
+
* Calls that carry no `orgName` argument are not chain-less: they still
|
|
45957
|
+
* belong to `this.orgName`, and that org lives on exactly one chain. Routing
|
|
45958
|
+
* them by the constructor's chain instead means a client configured
|
|
45959
|
+
* `network: "private"` reads the private chain for an org that lives on
|
|
45960
|
+
* public, and gets an empty answer rather than an error. So where an org is
|
|
45961
|
+
* known the org decides the chain, and the constructor's chain is what is
|
|
45962
|
+
* left when no org is known at all — the order `resolveAgentLookupNetwork`
|
|
45963
|
+
* already applies to agent metadata reads, and the order the dashboard
|
|
45964
|
+
* applies in `resolveChainForWallet`.
|
|
45965
|
+
*
|
|
45966
|
+
* Undefined when there is no default org, so callers keep falling back to
|
|
45967
|
+
* the client default.
|
|
45968
|
+
*/
|
|
45969
|
+
/** The switch's chain, unless this client named one of its own. */
|
|
45970
|
+
forcedNetwork() {
|
|
45971
|
+
return this._explicitChain ? void 0 : this._forcedNetwork;
|
|
45972
|
+
}
|
|
45973
|
+
async defaultOrgBrid() {
|
|
45974
|
+
if (this._explicitChain || !this.orgName) return void 0;
|
|
45975
|
+
return this.bridForOrg(this.orgName);
|
|
45976
|
+
}
|
|
45104
45977
|
async raiseIfError(resp) {
|
|
45105
45978
|
if (resp.ok) return;
|
|
45106
45979
|
throw await this.httpError(resp);
|
|
@@ -45111,11 +45984,28 @@ var Atbash = class _Atbash {
|
|
|
45111
45984
|
resp.status,
|
|
45112
45985
|
await safeText(resp),
|
|
45113
45986
|
resp.statusText,
|
|
45114
|
-
this.endpoint
|
|
45987
|
+
this.endpoint,
|
|
45988
|
+
requestPath(resp.url)
|
|
45115
45989
|
);
|
|
45116
45990
|
}
|
|
45117
|
-
/**
|
|
45991
|
+
/**
|
|
45992
|
+
* Wrap a transport failure (fetch threw, no response) as an AtbashAPIError.
|
|
45993
|
+
*
|
|
45994
|
+
* `HttpTransportError.kind` names the cause; the message is already
|
|
45995
|
+
* human-readable. `debug` echoes the original exception so operators can
|
|
45996
|
+
* cross-reference with node / undici logs when a class doesn't match.
|
|
45997
|
+
*/
|
|
45118
45998
|
transportError(err) {
|
|
45999
|
+
if (err instanceof HttpTransportError) {
|
|
46000
|
+
if (this.debug) {
|
|
46001
|
+
this.logger.warn?.(`[atbash] transport failed \u2014 kind=${err.kind}`, {
|
|
46002
|
+
kind: err.kind,
|
|
46003
|
+
cause: err.cause instanceof Error ? err.cause.message : String(err.cause ?? ""),
|
|
46004
|
+
endpoint: this.endpoint
|
|
46005
|
+
});
|
|
46006
|
+
}
|
|
46007
|
+
return new AtbashAPIError(0, err.message, "", this.endpoint);
|
|
46008
|
+
}
|
|
45119
46009
|
return new AtbashAPIError(0, errorMessage(err), "", this.endpoint);
|
|
45120
46010
|
}
|
|
45121
46011
|
async json(resp) {
|
|
@@ -45144,6 +46034,66 @@ var Atbash = class _Atbash {
|
|
|
45144
46034
|
return native.containsEvasionCharacters(text);
|
|
45145
46035
|
}
|
|
45146
46036
|
};
|
|
46037
|
+
function userFacingReason(reason, api2) {
|
|
46038
|
+
if (api2 && api2.status > 0) {
|
|
46039
|
+
const where = ` (HTTP ${api2.status}${api2.path ? ` from ${api2.path}` : ""})`;
|
|
46040
|
+
const b = api2.body.toLowerCase();
|
|
46041
|
+
if (b.includes("agent not registered")) {
|
|
46042
|
+
return `Agent not registered with Atbash: onboard it in the Atbash dashboard${where}.`;
|
|
46043
|
+
}
|
|
46044
|
+
if (b.includes("jailed")) {
|
|
46045
|
+
return `This agent is jailed; unjail it in the Atbash dashboard${where}.`;
|
|
46046
|
+
}
|
|
46047
|
+
if (b.includes("agent has no policy") || b.includes("no policy configured")) {
|
|
46048
|
+
return `This agent has no policy; attach one in the Atbash dashboard${where}.`;
|
|
46049
|
+
}
|
|
46050
|
+
if (b.includes("audit tier") || b.includes("verdict disabled") || b.includes("verdict not supported")) {
|
|
46051
|
+
return `The organisation's plan does not include checked decisions${where}.`;
|
|
46052
|
+
}
|
|
46053
|
+
return `The Atbash judge answered with an error${where}, so the action was not approved.`;
|
|
46054
|
+
}
|
|
46055
|
+
const text = api2 ? api2.body || reason : reason;
|
|
46056
|
+
return truncate(text.replace(/https?:\/\/[^\s)]+/g, "the judge"), 300);
|
|
46057
|
+
}
|
|
46058
|
+
var DEFAULT_DECISION_TIMEOUT_MS = 6e4;
|
|
46059
|
+
async function withDeadline(p, ms) {
|
|
46060
|
+
let timer;
|
|
46061
|
+
const deadline = new Promise((_, reject) => {
|
|
46062
|
+
timer = setTimeout(
|
|
46063
|
+
() => reject(
|
|
46064
|
+
new Error(
|
|
46065
|
+
`The judge did not give a decision within ${Math.round(ms / 1e3)} s, so the action was not approved. Check the network, or raise decisionTimeoutMs.`
|
|
46066
|
+
)
|
|
46067
|
+
),
|
|
46068
|
+
ms
|
|
46069
|
+
);
|
|
46070
|
+
});
|
|
46071
|
+
p.catch(() => void 0);
|
|
46072
|
+
try {
|
|
46073
|
+
return await Promise.race([p, deadline]);
|
|
46074
|
+
} finally {
|
|
46075
|
+
clearTimeout(timer);
|
|
46076
|
+
}
|
|
46077
|
+
}
|
|
46078
|
+
function verifyResponseSignature(bodyBytes, resp, verifyPubKey) {
|
|
46079
|
+
const sig = resp.headers.get("X-Atbash-Signature");
|
|
46080
|
+
if (!sig) {
|
|
46081
|
+
throw new SignatureVerificationError("missing X-Atbash-Signature header");
|
|
46082
|
+
}
|
|
46083
|
+
let ok;
|
|
46084
|
+
try {
|
|
46085
|
+
ok = native.verifySignature(bodyBytes, sig, verifyPubKey);
|
|
46086
|
+
} catch (err) {
|
|
46087
|
+
throw new SignatureVerificationError(
|
|
46088
|
+
`signature verification threw: ${errorMessage(err)}`
|
|
46089
|
+
);
|
|
46090
|
+
}
|
|
46091
|
+
if (!ok) {
|
|
46092
|
+
throw new SignatureVerificationError(
|
|
46093
|
+
"signature does not verify against configured verifyPubKey"
|
|
46094
|
+
);
|
|
46095
|
+
}
|
|
46096
|
+
}
|
|
45147
46097
|
function baseToolCall(raw2) {
|
|
45148
46098
|
return {
|
|
45149
46099
|
toolCallId: String(raw2.tool_call_id ?? ""),
|
|
@@ -45210,15 +46160,17 @@ function coerceOrgSubscription(raw2, orgName) {
|
|
|
45210
46160
|
is_active: Boolean(raw2.is_active)
|
|
45211
46161
|
};
|
|
45212
46162
|
}
|
|
45213
|
-
function
|
|
46163
|
+
function isRecord2(v) {
|
|
45214
46164
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
45215
46165
|
}
|
|
45216
46166
|
function optString(v) {
|
|
45217
46167
|
if (v === null || v === void 0) return void 0;
|
|
46168
|
+
if (typeof v === "object" || typeof v === "function") return void 0;
|
|
45218
46169
|
return typeof v === "string" ? v : String(v);
|
|
45219
46170
|
}
|
|
45220
46171
|
function optNumber(v) {
|
|
45221
46172
|
if (v === null || v === void 0) return void 0;
|
|
46173
|
+
if (typeof v === "object" || typeof v === "function") return void 0;
|
|
45222
46174
|
const n = Number(v);
|
|
45223
46175
|
return Number.isFinite(n) ? n : void 0;
|
|
45224
46176
|
}
|
|
@@ -45237,6 +46189,14 @@ function parseJson(bytes) {
|
|
|
45237
46189
|
const parsed = tryParseJson(bytes.toString("utf-8"));
|
|
45238
46190
|
return parsed === void 0 ? {} : parsed;
|
|
45239
46191
|
}
|
|
46192
|
+
function requestPath(url) {
|
|
46193
|
+
if (!url) return void 0;
|
|
46194
|
+
try {
|
|
46195
|
+
return new URL(url).pathname || void 0;
|
|
46196
|
+
} catch {
|
|
46197
|
+
return void 0;
|
|
46198
|
+
}
|
|
46199
|
+
}
|
|
45240
46200
|
async function safeText(resp) {
|
|
45241
46201
|
try {
|
|
45242
46202
|
return await resp.text();
|
|
@@ -45247,6 +46207,10 @@ async function safeText(resp) {
|
|
|
45247
46207
|
function errorMessage(err) {
|
|
45248
46208
|
return err instanceof Error ? err.message : String(err);
|
|
45249
46209
|
}
|
|
46210
|
+
function isEncryptionStateMismatch(err) {
|
|
46211
|
+
const msg = errorMessage(err);
|
|
46212
|
+
return msg.includes("must be a valid encryption envelope") || msg.includes("must be plaintext");
|
|
46213
|
+
}
|
|
45250
46214
|
function stringifyArgs(args) {
|
|
45251
46215
|
if (args === null || args === void 0) return "";
|
|
45252
46216
|
if (typeof args === "string") return args;
|
|
@@ -45257,12 +46221,28 @@ function stringifyArgs(args) {
|
|
|
45257
46221
|
}
|
|
45258
46222
|
}
|
|
45259
46223
|
var MAX_ACTION_LEN = 4e3;
|
|
45260
|
-
function truncate(text) {
|
|
45261
|
-
if (text.length <=
|
|
45262
|
-
return text.slice(0,
|
|
46224
|
+
function truncate(text, limit = MAX_ACTION_LEN) {
|
|
46225
|
+
if (text.length <= limit) return text;
|
|
46226
|
+
return text.slice(0, limit) + "\u2026";
|
|
46227
|
+
}
|
|
46228
|
+
|
|
46229
|
+
// src-ts/browser/key-path.ts
|
|
46230
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46231
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
46232
|
+
var KEY_FILENAMES = ["guard-client-key", "atbash-client-key"];
|
|
46233
|
+
var unavailable = (name2) => {
|
|
46234
|
+
throw new Error(`${name2} is not available in the browser bundle`);
|
|
46235
|
+
};
|
|
46236
|
+
function keyPathCandidates() {
|
|
46237
|
+
return unavailable("keyPathCandidates");
|
|
46238
|
+
}
|
|
46239
|
+
function chooseKeyPath(_input, _exists) {
|
|
46240
|
+
return unavailable("chooseKeyPath");
|
|
45263
46241
|
}
|
|
45264
46242
|
|
|
45265
46243
|
// src-ts/redact.ts
|
|
46244
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46245
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
45266
46246
|
function redactJsonStrings(value) {
|
|
45267
46247
|
if (typeof value === "string") {
|
|
45268
46248
|
return native.redactSecrets(value).redacted;
|
|
@@ -45281,6 +46261,8 @@ function redactJsonStrings(value) {
|
|
|
45281
46261
|
}
|
|
45282
46262
|
|
|
45283
46263
|
// src-ts/signature.ts
|
|
46264
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46265
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
45284
46266
|
function verifyJudgeResponseSignature(bodyBytes, signatureHex, pubKeyHex) {
|
|
45285
46267
|
if (!signatureHex) {
|
|
45286
46268
|
return { ok: false, reason: "missing X-Atbash-Signature header" };
|
|
@@ -45302,7 +46284,26 @@ function verifyJudgeResponseSignature(bodyBytes, signatureHex, pubKeyHex) {
|
|
|
45302
46284
|
};
|
|
45303
46285
|
}
|
|
45304
46286
|
|
|
46287
|
+
// src-ts/memory/boot-sync-message.ts
|
|
46288
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46289
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
46290
|
+
var BOOT_SYNC_HINT = "check the chain endpoint and orgName if the cause above does not explain it";
|
|
46291
|
+
function bootSyncFailureLine(cause) {
|
|
46292
|
+
const reason = cause instanceof Error ? cause.message : String(cause);
|
|
46293
|
+
const trimmed = reason.trim();
|
|
46294
|
+
return trimmed ? `[atbash] boot memory sync failed: ${trimmed}` : (
|
|
46295
|
+
// No cause to show: fall back to the advice rather than a bare colon.
|
|
46296
|
+
`[atbash] boot memory sync failed \u2014 ${BOOT_SYNC_HINT}`
|
|
46297
|
+
);
|
|
46298
|
+
}
|
|
46299
|
+
|
|
46300
|
+
// src-ts/memory/index.ts
|
|
46301
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46302
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
46303
|
+
|
|
45305
46304
|
// src-ts/browser/memory-crypto.ts
|
|
46305
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46306
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
45306
46307
|
var { Buffer: Buffer4 } = index;
|
|
45307
46308
|
var HKDF_INFO = new TextEncoder().encode("atbash:memory-encryption");
|
|
45308
46309
|
var KEY_LEN = 32;
|
|
@@ -45377,6 +46378,8 @@ async function decryptMemoryContent2(ciphertext, nonce, key3) {
|
|
|
45377
46378
|
}
|
|
45378
46379
|
|
|
45379
46380
|
// src-ts/browser/memory-scan.ts
|
|
46381
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46382
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
45380
46383
|
var STUB_MSG2 = "not available in @atbash/sdk browser bundle \u2014 scan memory server-side";
|
|
45381
46384
|
async function scanMemory(_entry, _auth, _opts) {
|
|
45382
46385
|
throw new Error(`scanMemory ${STUB_MSG2}`);
|
|
@@ -45386,6 +46389,8 @@ async function scanMemoryBatch(_entries, _auth, _opts) {
|
|
|
45386
46389
|
}
|
|
45387
46390
|
|
|
45388
46391
|
// src-ts/browser/memory-chain.ts
|
|
46392
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46393
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
45389
46394
|
var STUB_MSG3 = "not available in @atbash/sdk browser bundle \u2014 commit/rollback memory server-side";
|
|
45390
46395
|
async function commitMemoryVersion(_plaintext, _auth, _opts) {
|
|
45391
46396
|
throw new Error(`commitMemoryVersion ${STUB_MSG3}`);
|
|
@@ -45393,11 +46398,11 @@ async function commitMemoryVersion(_plaintext, _auth, _opts) {
|
|
|
45393
46398
|
async function getActiveMemoryId(_auth, _chainOpts) {
|
|
45394
46399
|
throw new Error(`getActiveMemoryId ${STUB_MSG3}`);
|
|
45395
46400
|
}
|
|
45396
|
-
async function
|
|
45397
|
-
throw new Error(`
|
|
46401
|
+
async function getRecentAgentMemory(_auth, _chainOpts) {
|
|
46402
|
+
throw new Error(`getRecentAgentMemory ${STUB_MSG3}`);
|
|
45398
46403
|
}
|
|
45399
|
-
async function
|
|
45400
|
-
throw new Error(`
|
|
46404
|
+
async function getActiveAgentMemory(_auth, _chainOpts) {
|
|
46405
|
+
throw new Error(`getActiveAgentMemory ${STUB_MSG3}`);
|
|
45401
46406
|
}
|
|
45402
46407
|
async function getMemoryHistory(_auth, _chainOpts) {
|
|
45403
46408
|
throw new Error(`getMemoryHistory ${STUB_MSG3}`);
|
|
@@ -45413,6 +46418,8 @@ async function rollbackMemory(_toId, _reason, _auth, _opts) {
|
|
|
45413
46418
|
}
|
|
45414
46419
|
|
|
45415
46420
|
// src-ts/browser/memory-classifier.ts
|
|
46421
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46422
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
45416
46423
|
var STUB_MSG4 = "not available in @atbash/sdk browser bundle \u2014 classify memory writes server-side";
|
|
45417
46424
|
var DEFAULT_MEMORY_WRITE_TOOL_NAMES = [
|
|
45418
46425
|
"write",
|
|
@@ -45434,103 +46441,17 @@ function classifyMemoryWrite(_event, _ctx, _opts = {}) {
|
|
|
45434
46441
|
throw new Error(`classifyMemoryWrite ${STUB_MSG4}`);
|
|
45435
46442
|
}
|
|
45436
46443
|
|
|
45437
|
-
// src-ts/memory
|
|
45438
|
-
|
|
45439
|
-
|
|
45440
|
-
|
|
45441
|
-
|
|
45442
|
-
|
|
45443
|
-
const argsObj = argsCandidate && typeof argsCandidate === "object" ? argsCandidate : {};
|
|
45444
|
-
const argsKeys = Object.keys(argsObj).slice(0, 20);
|
|
45445
|
-
const pickedPath = typeof argsObj.file_path === "string" && argsObj.file_path || typeof argsObj.path === "string" && argsObj.path || typeof argsObj.filename === "string" && argsObj.filename || null;
|
|
45446
|
-
const editsArr = Array.isArray(argsObj.edits) ? argsObj.edits : null;
|
|
45447
|
-
const firstEditKeys = editsArr && editsArr[0] && typeof editsArr[0] === "object" ? Object.keys(editsArr[0]).slice(0, 10) : null;
|
|
45448
|
-
const tool = ev.toolName ?? c.tool?.name ?? c.toolName ?? c.name ?? "(none)";
|
|
45449
|
-
logger2.info("[atbash][probe] before_tool_call", {
|
|
45450
|
-
toolName: tool,
|
|
45451
|
-
eventKeys: Object.keys(ev).slice(0, 20),
|
|
45452
|
-
ctxKeys: Object.keys(c).slice(0, 20),
|
|
45453
|
-
argsKeys,
|
|
45454
|
-
pickedPath,
|
|
45455
|
-
firstEditKeys,
|
|
45456
|
-
editsCount: editsArr?.length,
|
|
45457
|
-
memoryWrite: !!memEntry,
|
|
45458
|
-
memoryPath: memEntry?.key
|
|
45459
|
-
});
|
|
45460
|
-
}
|
|
45461
|
-
async function guardMemoryWrite(input) {
|
|
45462
|
-
const {
|
|
45463
|
-
event,
|
|
45464
|
-
ctx,
|
|
45465
|
-
auth,
|
|
45466
|
-
endpoint,
|
|
45467
|
-
verifyPubKey,
|
|
45468
|
-
orgName,
|
|
45469
|
-
threshold,
|
|
45470
|
-
patterns,
|
|
45471
|
-
toolNames,
|
|
45472
|
-
enforce = true,
|
|
45473
|
-
debug: debug2 = false,
|
|
45474
|
-
logger: logger2
|
|
45475
|
-
} = input;
|
|
45476
|
-
const memEntry = classifyMemoryWrite(event, ctx, { patterns, toolNames });
|
|
45477
|
-
if (debug2) emitDebugProbe(event, ctx, memEntry, logger2);
|
|
45478
|
-
if (!memEntry) return { handled: false };
|
|
45479
|
-
let scanResult;
|
|
45480
|
-
try {
|
|
45481
|
-
scanResult = await scanMemory(memEntry, auth, {
|
|
45482
|
-
endpoint,
|
|
45483
|
-
verifyPubKey,
|
|
45484
|
-
orgName,
|
|
45485
|
-
threshold
|
|
45486
|
-
});
|
|
45487
|
-
} catch (err) {
|
|
45488
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
45489
|
-
logger2?.warn?.("[atbash] memory scan failed", {
|
|
45490
|
-
path: memEntry.key,
|
|
45491
|
-
reason
|
|
45492
|
-
});
|
|
45493
|
-
return {
|
|
45494
|
-
handled: true,
|
|
45495
|
-
decision: enforce ? { allow: false, block: true, reason } : { allow: true }
|
|
45496
|
-
};
|
|
45497
|
-
}
|
|
45498
|
-
if (scanResult.verdict === "red") {
|
|
45499
|
-
logger2?.warn?.("[atbash] memory BLOCK", {
|
|
45500
|
-
path: memEntry.key,
|
|
45501
|
-
reason: scanResult.reason
|
|
45502
|
-
});
|
|
45503
|
-
return {
|
|
45504
|
-
handled: true,
|
|
45505
|
-
decision: enforce ? { allow: false, block: true, reason: scanResult.reason } : { allow: true },
|
|
45506
|
-
scanResult,
|
|
45507
|
-
committed: false
|
|
45508
|
-
};
|
|
45509
|
-
}
|
|
45510
|
-
commitMemoryVersion(memEntry.value, auth, {
|
|
45511
|
-
score: scanResult.score,
|
|
45512
|
-
orgName,
|
|
45513
|
-
endpoint
|
|
45514
|
-
}).catch((err) => {
|
|
45515
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
45516
|
-
logger2?.warn?.("[atbash] memory commit to chain failed", {
|
|
45517
|
-
path: memEntry.key,
|
|
45518
|
-
reason
|
|
45519
|
-
});
|
|
45520
|
-
});
|
|
45521
|
-
logger2?.info?.(
|
|
45522
|
-
scanResult.verdict === "yellow" ? "[atbash] memory HOLD" : "[atbash] memory ALLOW",
|
|
45523
|
-
{ path: memEntry.key, score: scanResult.score, reason: scanResult.reason }
|
|
45524
|
-
);
|
|
45525
|
-
return {
|
|
45526
|
-
handled: true,
|
|
45527
|
-
decision: { allow: true },
|
|
45528
|
-
scanResult,
|
|
45529
|
-
committed: true
|
|
45530
|
-
};
|
|
46444
|
+
// src-ts/browser/memory-guard.ts
|
|
46445
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46446
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
46447
|
+
var STUB_MSG5 = "not available in @atbash/sdk browser bundle \u2014 guard memory writes agent-side";
|
|
46448
|
+
async function guardMemoryWrite(_input) {
|
|
46449
|
+
throw new Error(`guardMemoryWrite ${STUB_MSG5}`);
|
|
45531
46450
|
}
|
|
45532
46451
|
|
|
45533
46452
|
// src-ts/memory/sync.ts
|
|
46453
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46454
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
45534
46455
|
var MemoryIntegrityError = class extends Error {
|
|
45535
46456
|
constructor(id, reason) {
|
|
45536
46457
|
super(`memory integrity check failed on id ${id}: ${reason}`);
|
|
@@ -45545,25 +46466,27 @@ async function syncLocalMemory(auth, pointer, opts = {}) {
|
|
|
45545
46466
|
const now = Date.now();
|
|
45546
46467
|
const withinTtl = !opts.force && now - pointer.checkedAt < ttl;
|
|
45547
46468
|
if (withinTtl) {
|
|
45548
|
-
return { drifted: false, pointer };
|
|
46469
|
+
return { drifted: false, checked: false, pointer };
|
|
45549
46470
|
}
|
|
45550
|
-
const currentId = await getActiveMemoryId(auth, opts.chainOpts);
|
|
46471
|
+
const currentId = await getActiveMemoryId(auth, opts.chainOpts, opts.filePath);
|
|
45551
46472
|
const nextPointer = { activeId: currentId, checkedAt: now };
|
|
45552
46473
|
if (currentId === pointer.activeId) {
|
|
45553
|
-
return { drifted: false, pointer: nextPointer };
|
|
46474
|
+
return { drifted: false, checked: true, pointer: nextPointer };
|
|
45554
46475
|
}
|
|
45555
46476
|
if (currentId === null) {
|
|
45556
|
-
return { drifted: true, current: null, pointer: nextPointer };
|
|
46477
|
+
return { drifted: true, checked: true, current: null, pointer: nextPointer };
|
|
45557
46478
|
}
|
|
45558
46479
|
const row = await getMemoryById(currentId, auth, opts.chainOpts);
|
|
45559
46480
|
if (row.decryptError) {
|
|
45560
46481
|
throw new MemoryIntegrityError(currentId, row.decryptError);
|
|
45561
46482
|
}
|
|
45562
|
-
return { drifted: true, current: row, pointer: nextPointer };
|
|
46483
|
+
return { drifted: true, checked: true, current: row, pointer: nextPointer };
|
|
45563
46484
|
}
|
|
45564
46485
|
|
|
45565
46486
|
// src-ts/browser/memory-pointer-store.ts
|
|
45566
|
-
|
|
46487
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46488
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
46489
|
+
var unavailable2 = (name2) => {
|
|
45567
46490
|
throw new Error(`${name2} is not available in the browser bundle`);
|
|
45568
46491
|
};
|
|
45569
46492
|
var PointerStore = class {
|
|
@@ -45577,32 +46500,38 @@ var PointerStore = class {
|
|
|
45577
46500
|
}
|
|
45578
46501
|
};
|
|
45579
46502
|
function defaultPointerPath(_workspaceDir) {
|
|
45580
|
-
return
|
|
46503
|
+
return unavailable2("defaultPointerPath");
|
|
45581
46504
|
}
|
|
45582
46505
|
|
|
45583
46506
|
// src-ts/browser/memory-file-logger.ts
|
|
45584
|
-
|
|
46507
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46508
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
46509
|
+
var unavailable3 = (name2) => {
|
|
45585
46510
|
throw new Error(`${name2} is not available in the browser bundle`);
|
|
45586
46511
|
};
|
|
45587
46512
|
function createFileLogger(_logFilePath, _hostLogger) {
|
|
45588
|
-
return
|
|
46513
|
+
return unavailable3("createFileLogger");
|
|
45589
46514
|
}
|
|
45590
46515
|
function defaultPluginLogPath(_workspaceDir) {
|
|
45591
|
-
return
|
|
46516
|
+
return unavailable3("defaultPluginLogPath");
|
|
45592
46517
|
}
|
|
45593
46518
|
|
|
45594
46519
|
// src-ts/browser/memory-read-classifier.ts
|
|
45595
|
-
|
|
46520
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46521
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
46522
|
+
var STUB_MSG6 = "not available in @atbash/sdk browser bundle \u2014 classify memory reads server-side";
|
|
45596
46523
|
var DEFAULT_MEMORY_READ_TOOL_NAMES = [
|
|
45597
46524
|
"memory_search",
|
|
45598
46525
|
"memory_get"
|
|
45599
46526
|
];
|
|
45600
46527
|
function classifyMemoryRead(_event, _ctx, _opts = {}) {
|
|
45601
|
-
throw new Error(`classifyMemoryRead ${
|
|
46528
|
+
throw new Error(`classifyMemoryRead ${STUB_MSG6}`);
|
|
45602
46529
|
}
|
|
45603
46530
|
|
|
45604
46531
|
// src-ts/browser/memory-guard-manager.ts
|
|
45605
|
-
|
|
46532
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
46533
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
46534
|
+
var unavailable4 = (name2) => {
|
|
45606
46535
|
throw new Error(`${name2} is not available in the browser bundle`);
|
|
45607
46536
|
};
|
|
45608
46537
|
var MemoryGuardManager = class {
|
|
@@ -45622,7 +46551,7 @@ var MemoryGuardManager = class {
|
|
|
45622
46551
|
}
|
|
45623
46552
|
};
|
|
45624
46553
|
function createMemoryGuardManager(_opts) {
|
|
45625
|
-
return
|
|
46554
|
+
return unavailable4("createMemoryGuardManager");
|
|
45626
46555
|
}
|
|
45627
46556
|
|
|
45628
46557
|
// src-ts/index.ts
|
|
@@ -45683,6 +46612,7 @@ function diffMemorySnapshots2(before, after) {
|
|
|
45683
46612
|
export {
|
|
45684
46613
|
Atbash,
|
|
45685
46614
|
AtbashAPIError,
|
|
46615
|
+
BOOT_SYNC_HINT,
|
|
45686
46616
|
DEFAULT_BLOCKCHAIN_RID,
|
|
45687
46617
|
DEFAULT_CHROMIA_NODE_URLS,
|
|
45688
46618
|
DEFAULT_ENDPOINT,
|
|
@@ -45690,14 +46620,26 @@ export {
|
|
|
45690
46620
|
DEFAULT_MEMORY_READ_TOOL_NAMES,
|
|
45691
46621
|
DEFAULT_MEMORY_WRITE_TOOL_NAMES,
|
|
45692
46622
|
EciesDomain,
|
|
46623
|
+
HttpClient,
|
|
46624
|
+
HttpTransportError,
|
|
46625
|
+
KEY_FILENAMES,
|
|
45693
46626
|
MemoryGuardManager,
|
|
45694
46627
|
MemoryIntegrityError,
|
|
46628
|
+
PRIVATE_CHAIN,
|
|
46629
|
+
PUBLIC_CHAIN,
|
|
45695
46630
|
PointerStore,
|
|
45696
46631
|
SignatureVerificationError,
|
|
46632
|
+
bootSyncFailureLine,
|
|
46633
|
+
buildAllowedJudgeHosts,
|
|
46634
|
+
canonicalAllow,
|
|
46635
|
+
chainForNetwork,
|
|
46636
|
+
chooseKeyPath,
|
|
45697
46637
|
claimHashHex,
|
|
45698
46638
|
classifyMemoryRead,
|
|
45699
46639
|
classifyMemoryWrite,
|
|
46640
|
+
columnAad,
|
|
45700
46641
|
commitMemoryVersion,
|
|
46642
|
+
configureEvents,
|
|
45701
46643
|
containsEvasionCharacters2 as containsEvasionCharacters,
|
|
45702
46644
|
containsSecret2 as containsSecret,
|
|
45703
46645
|
createFileLogger,
|
|
@@ -45713,28 +46655,36 @@ export {
|
|
|
45713
46655
|
encryptForOrg,
|
|
45714
46656
|
encryptMemoryContent2 as encryptMemoryContent,
|
|
45715
46657
|
encryptedLength,
|
|
46658
|
+
eventsAreOn,
|
|
45716
46659
|
flushTelemetry,
|
|
45717
46660
|
generateKeypair2 as generateKeypair,
|
|
45718
|
-
|
|
46661
|
+
getActiveAgentMemory,
|
|
45719
46662
|
getActiveMemoryId,
|
|
45720
|
-
getAllAgentMemory,
|
|
45721
46663
|
getConfigDir,
|
|
45722
46664
|
getConfigPath,
|
|
45723
46665
|
getMemoryById,
|
|
45724
46666
|
getMemoryHistory,
|
|
46667
|
+
getRecentAgentMemory,
|
|
45725
46668
|
getRollbackHistory,
|
|
45726
46669
|
guardMemoryWrite,
|
|
46670
|
+
isEnvelope,
|
|
45727
46671
|
isValidPrivateKey2 as isValidPrivateKey,
|
|
46672
|
+
keyFingerprintOf,
|
|
46673
|
+
keyPathCandidates,
|
|
45728
46674
|
loadAgent2 as loadAgent,
|
|
45729
46675
|
loadAgentFromFile,
|
|
45730
46676
|
loadUserConfig,
|
|
45731
46677
|
normalizeActionForHash,
|
|
46678
|
+
normalizeActionType,
|
|
45732
46679
|
normalizeForMatching2 as normalizeForMatching,
|
|
45733
46680
|
normalizeStatus,
|
|
45734
46681
|
normalizeVerdict,
|
|
46682
|
+
packEnvelope,
|
|
46683
|
+
parseEnvelope,
|
|
45735
46684
|
pubkeyToHex,
|
|
45736
46685
|
recordCall,
|
|
45737
46686
|
recordDuration,
|
|
46687
|
+
recordEvent,
|
|
45738
46688
|
redactJsonStrings,
|
|
45739
46689
|
redactSecrets2 as redactSecrets,
|
|
45740
46690
|
resolve,
|
|
@@ -45775,4 +46725,3 @@ postchain-client/built/esm/index.js:
|
|
|
45775
46725
|
@noble/ciphers/utils.js:
|
|
45776
46726
|
(*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) *)
|
|
45777
46727
|
*/
|
|
45778
|
-
//# sourceMappingURL=browser.mjs.map
|