@atbash/sdk 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.mts +199 -21
- package/dist/browser.mjs +753 -318
- package/dist/browser.mjs.map +1 -1
- package/dist/index.d.mts +199 -21
- package/dist/index.d.ts +199 -21
- package/dist/index.js +457 -68
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +446 -68
- package/dist/index.mjs.map +1 -1
- package/index.js +52 -52
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -2995,8 +2995,8 @@ var HttpClient = class {
|
|
|
2995
2995
|
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
2996
2996
|
this.timeoutMs = timeoutMs;
|
|
2997
2997
|
}
|
|
2998
|
-
buildUrl(
|
|
2999
|
-
const url = new URL(this.baseUrl +
|
|
2998
|
+
buildUrl(path6, query) {
|
|
2999
|
+
const url = new URL(this.baseUrl + path6);
|
|
3000
3000
|
if (query) {
|
|
3001
3001
|
for (const [k, v] of Object.entries(query)) {
|
|
3002
3002
|
if (v !== void 0 && v !== null && v !== "") {
|
|
@@ -3006,14 +3006,14 @@ var HttpClient = class {
|
|
|
3006
3006
|
}
|
|
3007
3007
|
return url.toString();
|
|
3008
3008
|
}
|
|
3009
|
-
async get(
|
|
3010
|
-
return this.fetch(this.buildUrl(
|
|
3009
|
+
async get(path6, query, headers) {
|
|
3010
|
+
return this.fetch(this.buildUrl(path6, query), {
|
|
3011
3011
|
method: "GET",
|
|
3012
3012
|
...headers && { headers }
|
|
3013
3013
|
});
|
|
3014
3014
|
}
|
|
3015
|
-
async post(
|
|
3016
|
-
return this.fetch(this.buildUrl(
|
|
3015
|
+
async post(path6, body, headers) {
|
|
3016
|
+
return this.fetch(this.buildUrl(path6), {
|
|
3017
3017
|
method: "POST",
|
|
3018
3018
|
headers: { "Content-Type": "application/json", ...headers },
|
|
3019
3019
|
body: JSON.stringify(body)
|
|
@@ -3326,13 +3326,22 @@ var Atbash = class _Atbash {
|
|
|
3326
3326
|
return this.auth.privkey;
|
|
3327
3327
|
}
|
|
3328
3328
|
/* ── agent existence (/api/ai/exists) ──────────────────────────────────── */
|
|
3329
|
-
/**
|
|
3330
|
-
|
|
3329
|
+
/**
|
|
3330
|
+
* `GET /api/ai/exists?pubkey=…[&network=…]` — defaults to this client's
|
|
3331
|
+
* pubkey. Pass `opts.network` when the caller already knows which
|
|
3332
|
+
* network the agent lives on (e.g. after resolving via `orgName`) so
|
|
3333
|
+
* the dashboard queries that chain directly instead of falling back
|
|
3334
|
+
* across public → private, which double-round-trips and can return
|
|
3335
|
+
* false negatives when the fallback chain client is misconfigured.
|
|
3336
|
+
*/
|
|
3337
|
+
async checkAgentExists(pubkey, opts) {
|
|
3331
3338
|
const pk = pubkey ?? this.auth.pubkey;
|
|
3332
3339
|
return this.track("checkAgentExists", pk, async () => {
|
|
3340
|
+
const query = { pubkey: pk };
|
|
3341
|
+
if (opts?.network) query.network = opts.network;
|
|
3333
3342
|
const resp = await this.http.get(
|
|
3334
3343
|
"/api/ai/exists",
|
|
3335
|
-
|
|
3344
|
+
query,
|
|
3336
3345
|
this.authHeaders()
|
|
3337
3346
|
);
|
|
3338
3347
|
await this.raiseIfError(resp);
|
|
@@ -3350,7 +3359,9 @@ var Atbash = class _Atbash {
|
|
|
3350
3359
|
recordCall("logToolCall", void 0, this.auth.pubkey);
|
|
3351
3360
|
let exists;
|
|
3352
3361
|
try {
|
|
3353
|
-
exists = await this.checkAgentExists(
|
|
3362
|
+
exists = await this.checkAgentExists(this.auth.pubkey, {
|
|
3363
|
+
network: options.chainOpts?.network
|
|
3364
|
+
});
|
|
3354
3365
|
} catch (err) {
|
|
3355
3366
|
recordDuration("logToolCall", performance.now() - start, "error");
|
|
3356
3367
|
return { success: false, toolCallId: null, error: errorMessage(err) };
|
|
@@ -3364,7 +3375,7 @@ var Atbash = class _Atbash {
|
|
|
3364
3375
|
};
|
|
3365
3376
|
}
|
|
3366
3377
|
const toolCallId = generateToolCallId();
|
|
3367
|
-
const brid = options.chainOpts
|
|
3378
|
+
const brid = this.bridFromChainOpts(options.chainOpts);
|
|
3368
3379
|
try {
|
|
3369
3380
|
const signedHex = native.signLogToolCall(
|
|
3370
3381
|
toolCallId,
|
|
@@ -3475,6 +3486,8 @@ var Atbash = class _Atbash {
|
|
|
3475
3486
|
}
|
|
3476
3487
|
}
|
|
3477
3488
|
const data = parseJson(bodyBytes);
|
|
3489
|
+
const rawScore = data.score;
|
|
3490
|
+
const score = typeof rawScore === "number" && Number.isInteger(rawScore) && rawScore >= 1 && rawScore <= 10 ? rawScore : void 0;
|
|
3478
3491
|
return {
|
|
3479
3492
|
verdict: normalizeVerdict(data.verdict),
|
|
3480
3493
|
actionType: String(data.action_type ?? ""),
|
|
@@ -3485,7 +3498,8 @@ var Atbash = class _Atbash {
|
|
|
3485
3498
|
toolCallId: String(data.tool_call_id ?? logResult.toolCallId),
|
|
3486
3499
|
onChain: Boolean(data.on_chain),
|
|
3487
3500
|
enforced: Boolean(data.enforced),
|
|
3488
|
-
enforcementMode: String(data.enforcement_mode ?? "")
|
|
3501
|
+
enforcementMode: String(data.enforcement_mode ?? ""),
|
|
3502
|
+
score
|
|
3489
3503
|
};
|
|
3490
3504
|
}
|
|
3491
3505
|
/* ── audit_tool_call (redact → judge → decision) ───────────────────────── */
|
|
@@ -4113,13 +4127,13 @@ function verifyJudgeResponseSignature(bodyBytes, signatureHex, pubKeyHex) {
|
|
|
4113
4127
|
}
|
|
4114
4128
|
|
|
4115
4129
|
// src-ts/memory/crypto.ts
|
|
4116
|
-
function deriveMemoryKey(privkey) {
|
|
4130
|
+
async function deriveMemoryKey(privkey) {
|
|
4117
4131
|
return native.deriveMemoryKey(privkey);
|
|
4118
4132
|
}
|
|
4119
|
-
function encryptMemoryContent(plaintext, key3) {
|
|
4133
|
+
async function encryptMemoryContent(plaintext, key3) {
|
|
4120
4134
|
return native.encryptMemoryContent(plaintext, key3);
|
|
4121
4135
|
}
|
|
4122
|
-
function decryptMemoryContent(ciphertext, nonce, key3) {
|
|
4136
|
+
async function decryptMemoryContent(ciphertext, nonce, key3) {
|
|
4123
4137
|
return native.decryptMemoryContent(ciphertext, nonce, key3);
|
|
4124
4138
|
}
|
|
4125
4139
|
|
|
@@ -4213,7 +4227,7 @@ async function scanMemory(entry, auth, opts) {
|
|
|
4213
4227
|
});
|
|
4214
4228
|
const verdict = mapVerdict(result.actionType, result.confidence, threshold);
|
|
4215
4229
|
const { score: parsedScore, cleanReason } = parseScoreFromReason(result.reason);
|
|
4216
|
-
const score = parsedScore ?? defaultScoreForVerdict(verdict);
|
|
4230
|
+
const score = result.score ?? parsedScore ?? defaultScoreForVerdict(verdict);
|
|
4217
4231
|
if (prefilter && prefilter.verdict === "yellow" && verdict === "green") {
|
|
4218
4232
|
return {
|
|
4219
4233
|
safe: false,
|
|
@@ -9127,8 +9141,8 @@ Reporter$3.prototype.wrapResult = function wrapResult(result) {
|
|
|
9127
9141
|
errors: state2.errors
|
|
9128
9142
|
};
|
|
9129
9143
|
};
|
|
9130
|
-
function ReporterError$1(
|
|
9131
|
-
this.path =
|
|
9144
|
+
function ReporterError$1(path6, msg) {
|
|
9145
|
+
this.path = path6;
|
|
9132
9146
|
this.rethrow(msg);
|
|
9133
9147
|
}
|
|
9134
9148
|
inherits$v(ReporterError$1, Error);
|
|
@@ -29349,8 +29363,8 @@ Reporter.prototype.wrapResult = function wrapResult2(result) {
|
|
|
29349
29363
|
errors: state2.errors
|
|
29350
29364
|
};
|
|
29351
29365
|
};
|
|
29352
|
-
function ReporterError(
|
|
29353
|
-
this.path =
|
|
29366
|
+
function ReporterError(path6, msg) {
|
|
29367
|
+
this.path = path6;
|
|
29354
29368
|
this.rethrow(msg);
|
|
29355
29369
|
}
|
|
29356
29370
|
inherits(ReporterError, Error);
|
|
@@ -32380,8 +32394,8 @@ var parseUtil = {};
|
|
|
32380
32394
|
const errors_js_12 = errors$3;
|
|
32381
32395
|
const en_js_12 = __importDefault2(en);
|
|
32382
32396
|
const makeIssue = (params) => {
|
|
32383
|
-
const { data, path:
|
|
32384
|
-
const fullPath = [...
|
|
32397
|
+
const { data, path: path6, errorMaps, issueData } = params;
|
|
32398
|
+
const fullPath = [...path6, ...issueData.path || []];
|
|
32385
32399
|
const fullIssue = {
|
|
32386
32400
|
...issueData,
|
|
32387
32401
|
path: fullPath
|
|
@@ -32518,11 +32532,11 @@ var errorUtil_js_1 = errorUtil$1;
|
|
|
32518
32532
|
var parseUtil_js_1 = parseUtil;
|
|
32519
32533
|
var util_js_1 = util;
|
|
32520
32534
|
var ParseInputLazyPath = class {
|
|
32521
|
-
constructor(parent, value,
|
|
32535
|
+
constructor(parent, value, path6, key3) {
|
|
32522
32536
|
this._cachedPath = [];
|
|
32523
32537
|
this.parent = parent;
|
|
32524
32538
|
this.data = value;
|
|
32525
|
-
this._path =
|
|
32539
|
+
this._path = path6;
|
|
32526
32540
|
this._key = key3;
|
|
32527
32541
|
}
|
|
32528
32542
|
get path() {
|
|
@@ -39428,21 +39442,21 @@ function createTimeoutController(timeout) {
|
|
|
39428
39442
|
const timeoutId = setTimeout(() => controller.abort(timeoutError), timeout);
|
|
39429
39443
|
return { controller, timeoutId };
|
|
39430
39444
|
}
|
|
39431
|
-
function handleRequest(method,
|
|
39445
|
+
function handleRequest(method, path6, endpoint, timeout, postObject) {
|
|
39432
39446
|
return __awaiter$2(this, void 0, void 0, function* () {
|
|
39433
39447
|
if (method == enums_1$2.Method.GET) {
|
|
39434
|
-
return yield get(
|
|
39448
|
+
return yield get(path6, endpoint, timeout);
|
|
39435
39449
|
} else {
|
|
39436
|
-
return yield post(
|
|
39450
|
+
return yield post(path6, endpoint, timeout, postObject);
|
|
39437
39451
|
}
|
|
39438
39452
|
});
|
|
39439
39453
|
}
|
|
39440
|
-
function get(
|
|
39454
|
+
function get(path6, endpoint, timeout) {
|
|
39441
39455
|
return __awaiter$2(this, void 0, void 0, function* () {
|
|
39442
|
-
logger.debug(`GET URL ${new URL(
|
|
39456
|
+
logger.debug(`GET URL ${new URL(path6, endpoint).href}`);
|
|
39443
39457
|
try {
|
|
39444
39458
|
const { controller, timeoutId } = createTimeoutController(timeout);
|
|
39445
|
-
const response = yield fetch(new URL(
|
|
39459
|
+
const response = yield fetch(new URL(path6, endpoint).href, {
|
|
39446
39460
|
signal: controller === null || controller === void 0 ? void 0 : controller.signal
|
|
39447
39461
|
});
|
|
39448
39462
|
if (timeoutId)
|
|
@@ -39480,9 +39494,9 @@ function constructBufferResponseBody(response) {
|
|
|
39480
39494
|
return responseText ? responseText : response.statusText;
|
|
39481
39495
|
});
|
|
39482
39496
|
}
|
|
39483
|
-
function post(
|
|
39497
|
+
function post(path6, endpoint, timeout, requestBody) {
|
|
39484
39498
|
return __awaiter$2(this, void 0, void 0, function* () {
|
|
39485
|
-
logger.debug(`POST URL ${new URL(
|
|
39499
|
+
logger.debug(`POST URL ${new URL(path6, endpoint).href}`);
|
|
39486
39500
|
logger.debug(`POST body ${JSON.stringify(requestBody)}`);
|
|
39487
39501
|
if (buffer_1.Buffer.isBuffer(requestBody)) {
|
|
39488
39502
|
try {
|
|
@@ -39496,7 +39510,7 @@ function post(path3, endpoint, timeout, requestBody) {
|
|
|
39496
39510
|
},
|
|
39497
39511
|
signal: controller === null || controller === void 0 ? void 0 : controller.signal
|
|
39498
39512
|
};
|
|
39499
|
-
const response = yield fetch(new URL(
|
|
39513
|
+
const response = yield fetch(new URL(path6, endpoint).href, requestOptions);
|
|
39500
39514
|
if (timeoutId)
|
|
39501
39515
|
clearTimeout(timeoutId);
|
|
39502
39516
|
const transactionTimestamp = response.headers.get("X-Transaction-Timestamp");
|
|
@@ -39507,7 +39521,7 @@ function post(path3, endpoint, timeout, requestBody) {
|
|
|
39507
39521
|
} else {
|
|
39508
39522
|
try {
|
|
39509
39523
|
const { controller, timeoutId } = createTimeoutController(timeout);
|
|
39510
|
-
const response = yield fetch(new URL(
|
|
39524
|
+
const response = yield fetch(new URL(path6, endpoint).href, {
|
|
39511
39525
|
method: "post",
|
|
39512
39526
|
body: JSON.stringify(requestBody),
|
|
39513
39527
|
headers: {
|
|
@@ -39687,10 +39701,10 @@ function requireFailoverStrategies() {
|
|
|
39687
39701
|
}
|
|
39688
39702
|
}
|
|
39689
39703
|
function abortOnError(_a2) {
|
|
39690
|
-
return __awaiter2(this, arguments, void 0, function* ({ method, path:
|
|
39704
|
+
return __awaiter2(this, arguments, void 0, function* ({ method, path: path6, config: config2, postObject, timeoutOverride }) {
|
|
39691
39705
|
return yield retryRequest({
|
|
39692
39706
|
method,
|
|
39693
|
-
path:
|
|
39707
|
+
path: path6,
|
|
39694
39708
|
config: config2,
|
|
39695
39709
|
postObject,
|
|
39696
39710
|
timeoutOverride,
|
|
@@ -39701,10 +39715,10 @@ function requireFailoverStrategies() {
|
|
|
39701
39715
|
});
|
|
39702
39716
|
}
|
|
39703
39717
|
function tryNextOnError(_a2) {
|
|
39704
|
-
return __awaiter2(this, arguments, void 0, function* ({ method, path:
|
|
39718
|
+
return __awaiter2(this, arguments, void 0, function* ({ method, path: path6, config: config2, postObject, timeoutOverride }) {
|
|
39705
39719
|
return yield retryRequest({
|
|
39706
39720
|
method,
|
|
39707
|
-
path:
|
|
39721
|
+
path: path6,
|
|
39708
39722
|
config: config2,
|
|
39709
39723
|
postObject,
|
|
39710
39724
|
timeoutOverride,
|
|
@@ -39720,7 +39734,7 @@ function requireFailoverStrategies() {
|
|
|
39720
39734
|
return endpointPoolLength - (endpointPoolLength - 1) / 3;
|
|
39721
39735
|
}
|
|
39722
39736
|
function queryMajority(_a2) {
|
|
39723
|
-
return __awaiter2(this, arguments, void 0, function* ({ method, path:
|
|
39737
|
+
return __awaiter2(this, arguments, void 0, function* ({ method, path: path6, config: config2, postObject, timeoutOverride }) {
|
|
39724
39738
|
var _b;
|
|
39725
39739
|
const bftMajorityThreshold = calculateBftMajorityThreshold(config2.endpointPool.length);
|
|
39726
39740
|
const failureThreshold = config2.endpointPool.length - bftMajorityThreshold + 1;
|
|
@@ -39731,7 +39745,7 @@ function requireFailoverStrategies() {
|
|
|
39731
39745
|
const promises = availableNodes.map((node2) => __awaiter2(this, void 0, void 0, function* () {
|
|
39732
39746
|
try {
|
|
39733
39747
|
const requestTimeout = timeoutOverride !== null && timeoutOverride !== void 0 ? timeoutOverride : config2.responseTimeout;
|
|
39734
|
-
const response = yield (0, httpUtil_1.handleRequest)(method,
|
|
39748
|
+
const response = yield (0, httpUtil_1.handleRequest)(method, path6, node2.url, requestTimeout, postObject);
|
|
39735
39749
|
const { statusCode } = response;
|
|
39736
39750
|
if (statusCode && (0, http_utils_1.isSuccessfulStatusCode)(statusCode)) {
|
|
39737
39751
|
outcomes.push({ type: "SUCCESS", result: response });
|
|
@@ -39778,7 +39792,7 @@ function requireFailoverStrategies() {
|
|
|
39778
39792
|
});
|
|
39779
39793
|
}
|
|
39780
39794
|
function singleEndpoint(_a2) {
|
|
39781
|
-
return __awaiter2(this, arguments, void 0, function* ({ method, path:
|
|
39795
|
+
return __awaiter2(this, arguments, void 0, function* ({ method, path: path6, config: config2, postObject, timeoutOverride }) {
|
|
39782
39796
|
let statusCode = null;
|
|
39783
39797
|
let rspBody = null;
|
|
39784
39798
|
let error4 = null;
|
|
@@ -39789,7 +39803,7 @@ function requireFailoverStrategies() {
|
|
|
39789
39803
|
}
|
|
39790
39804
|
for (let attempt = 0; attempt < config2.attemptsPerEndpoint; attempt++) {
|
|
39791
39805
|
const requestTimeout = timeoutOverride !== null && timeoutOverride !== void 0 ? timeoutOverride : config2.responseTimeout;
|
|
39792
|
-
const response = yield (0, httpUtil_1.handleRequest)(method,
|
|
39806
|
+
const response = yield (0, httpUtil_1.handleRequest)(method, path6, endpoint.url, requestTimeout, postObject);
|
|
39793
39807
|
if (response) {
|
|
39794
39808
|
({ error: error4, statusCode, rspBody, transactionTimestamp } = response);
|
|
39795
39809
|
}
|
|
@@ -39804,7 +39818,7 @@ function requireFailoverStrategies() {
|
|
|
39804
39818
|
});
|
|
39805
39819
|
}
|
|
39806
39820
|
function retryRequest(_a2) {
|
|
39807
|
-
return __awaiter2(this, arguments, void 0, function* ({ method, path:
|
|
39821
|
+
return __awaiter2(this, arguments, void 0, function* ({ method, path: path6, config: config2, postObject, useNextNodeOnError, recoveryThreshold, timeoutOverride }) {
|
|
39808
39822
|
var _b, _c, _d;
|
|
39809
39823
|
let statusCode = null;
|
|
39810
39824
|
let rspBody = null;
|
|
@@ -39815,7 +39829,7 @@ function requireFailoverStrategies() {
|
|
|
39815
39829
|
for (const node2 of availableNodes) {
|
|
39816
39830
|
for (let attempt = 0; attempt < config2.attemptsPerEndpoint; attempt++) {
|
|
39817
39831
|
const requestTimeout = timeoutOverride !== null && timeoutOverride !== void 0 ? timeoutOverride : config2.responseTimeout;
|
|
39818
|
-
const response = yield (0, httpUtil_1.handleRequest)(method,
|
|
39832
|
+
const response = yield (0, httpUtil_1.handleRequest)(method, path6, node2.url, requestTimeout, postObject);
|
|
39819
39833
|
error4 = (_b = response === null || response === void 0 ? void 0 : response.error) !== null && _b !== void 0 ? _b : null;
|
|
39820
39834
|
statusCode = (_c = response === null || response === void 0 ? void 0 : response.statusCode) !== null && _c !== void 0 ? _c : null;
|
|
39821
39835
|
rspBody = (_d = response === null || response === void 0 ? void 0 : response.rspBody) !== null && _d !== void 0 ? _d : null;
|
|
@@ -39958,19 +39972,19 @@ function requireRequestWithFailoverStrategy() {
|
|
|
39958
39972
|
const enums_12 = enums;
|
|
39959
39973
|
const failoverStrategies_1 = requireFailoverStrategies();
|
|
39960
39974
|
function requestWithFailoverStrategy$1(method_1, path_1, config_1, postObject_1) {
|
|
39961
|
-
return __awaiter2(this, arguments, void 0, function* (method,
|
|
39975
|
+
return __awaiter2(this, arguments, void 0, function* (method, path6, config2, postObject, forceSingleEndpoint = false, timeoutOverride) {
|
|
39962
39976
|
switch (config2.failoverStrategy) {
|
|
39963
39977
|
case enums_12.FailoverStrategy.AbortOnError:
|
|
39964
|
-
return yield (0, failoverStrategies_1.abortOnError)({ method, path:
|
|
39978
|
+
return yield (0, failoverStrategies_1.abortOnError)({ method, path: path6, config: config2, postObject, timeoutOverride });
|
|
39965
39979
|
case enums_12.FailoverStrategy.TryNextOnError:
|
|
39966
|
-
return yield (0, failoverStrategies_1.tryNextOnError)({ method, path:
|
|
39980
|
+
return yield (0, failoverStrategies_1.tryNextOnError)({ method, path: path6, config: config2, postObject, timeoutOverride });
|
|
39967
39981
|
case enums_12.FailoverStrategy.SingleEndpoint:
|
|
39968
|
-
return yield (0, failoverStrategies_1.singleEndpoint)({ method, path:
|
|
39982
|
+
return yield (0, failoverStrategies_1.singleEndpoint)({ method, path: path6, config: config2, postObject, timeoutOverride });
|
|
39969
39983
|
case enums_12.FailoverStrategy.QueryMajority:
|
|
39970
39984
|
if (forceSingleEndpoint) {
|
|
39971
|
-
return yield (0, failoverStrategies_1.singleEndpoint)({ method, path:
|
|
39985
|
+
return yield (0, failoverStrategies_1.singleEndpoint)({ method, path: path6, config: config2, postObject, timeoutOverride });
|
|
39972
39986
|
}
|
|
39973
|
-
return yield (0, failoverStrategies_1.queryMajority)({ method, path:
|
|
39987
|
+
return yield (0, failoverStrategies_1.queryMajority)({ method, path: path6, config: config2, postObject, timeoutOverride });
|
|
39974
39988
|
default:
|
|
39975
39989
|
throw new Error(`Unsupported failover strategy: ${config2.failoverStrategy}`);
|
|
39976
39990
|
}
|
|
@@ -41169,7 +41183,7 @@ var networkSettings = {};
|
|
|
41169
41183
|
const restNetworkSettingsValidationContext = RestNetworkSettingsSchema.safeParse(networkSettings2);
|
|
41170
41184
|
if ("error" in restNetworkSettingsValidationContext) {
|
|
41171
41185
|
const { error: { issues } = {} } = restNetworkSettingsValidationContext;
|
|
41172
|
-
const errorMessage2 = issues === null || issues === void 0 ? void 0 : issues.map(({ message, path:
|
|
41186
|
+
const errorMessage2 = issues === null || issues === void 0 ? void 0 : issues.map(({ message, path: path6 }) => `${path6[0]}: ${message}`).join(", ");
|
|
41173
41187
|
if (throwOnError) {
|
|
41174
41188
|
throw new Error(errorMessage2);
|
|
41175
41189
|
}
|
|
@@ -42414,8 +42428,8 @@ async function commitMemoryVersion(plaintext, auth, opts) {
|
|
|
42414
42428
|
"commitMemoryVersion: score must be an integer in [1, 10]"
|
|
42415
42429
|
);
|
|
42416
42430
|
}
|
|
42417
|
-
const key3 = deriveMemoryKey(auth.privkey);
|
|
42418
|
-
const { ciphertext, nonce } = encryptMemoryContent(plaintext, key3);
|
|
42431
|
+
const key3 = await deriveMemoryKey(auth.privkey);
|
|
42432
|
+
const { ciphertext, nonce } = await encryptMemoryContent(plaintext, key3);
|
|
42419
42433
|
const chainOpts = await resolveChainOptsForOrg(opts, auth);
|
|
42420
42434
|
const client = await buildChainClient(chainOpts);
|
|
42421
42435
|
const { keyPair, sigProvider } = buildSigner(auth);
|
|
@@ -42441,13 +42455,13 @@ function toBuf(val) {
|
|
|
42441
42455
|
}
|
|
42442
42456
|
throw new Error("toBuf: unsupported byte_array shape from chain");
|
|
42443
42457
|
}
|
|
42444
|
-
function decryptRow(row, key3) {
|
|
42458
|
+
async function decryptRow(row, key3) {
|
|
42445
42459
|
const ciphertext = toBuf(row.content_cipher);
|
|
42446
42460
|
const nonce = toBuf(row.nonce);
|
|
42447
42461
|
let content;
|
|
42448
42462
|
let decryptError;
|
|
42449
42463
|
try {
|
|
42450
|
-
content = decryptMemoryContent(ciphertext, nonce, key3);
|
|
42464
|
+
content = await decryptMemoryContent(ciphertext, nonce, key3);
|
|
42451
42465
|
} catch (err) {
|
|
42452
42466
|
content = "";
|
|
42453
42467
|
decryptError = err instanceof Error ? err.message : String(err);
|
|
@@ -42464,36 +42478,43 @@ function decryptRow(row, key3) {
|
|
|
42464
42478
|
updatedAt: row.updated_at ?? row.created_at
|
|
42465
42479
|
};
|
|
42466
42480
|
}
|
|
42481
|
+
async function getActiveMemoryId(auth, chainOpts) {
|
|
42482
|
+
const client = await buildChainClient(chainOpts);
|
|
42483
|
+
const raw2 = await client.query("get_active_memory_id", {
|
|
42484
|
+
agent_pubkey: auth.pubkey
|
|
42485
|
+
});
|
|
42486
|
+
return raw2 ?? null;
|
|
42487
|
+
}
|
|
42467
42488
|
async function getActiveMemory(auth, chainOpts) {
|
|
42468
42489
|
const client = await buildChainClient(chainOpts);
|
|
42469
|
-
const key3 = deriveMemoryKey(auth.privkey);
|
|
42490
|
+
const key3 = await deriveMemoryKey(auth.privkey);
|
|
42470
42491
|
const rows = await client.query("get_agent_memory", {
|
|
42471
42492
|
agent_pubkey: auth.pubkey
|
|
42472
42493
|
});
|
|
42473
|
-
return rows.map((r2) => decryptRow(r2, key3));
|
|
42494
|
+
return Promise.all(rows.map((r2) => decryptRow(r2, key3)));
|
|
42474
42495
|
}
|
|
42475
42496
|
async function getAllAgentMemory(auth, chainOpts) {
|
|
42476
42497
|
const client = await buildChainClient(chainOpts);
|
|
42477
|
-
const key3 = deriveMemoryKey(auth.privkey);
|
|
42498
|
+
const key3 = await deriveMemoryKey(auth.privkey);
|
|
42478
42499
|
const rows = await client.query("get_all_agent_memory", {
|
|
42479
42500
|
agent_pubkey: auth.pubkey
|
|
42480
42501
|
});
|
|
42481
|
-
return rows.map((r2) => decryptRow(r2, key3));
|
|
42502
|
+
return Promise.all(rows.map((r2) => decryptRow(r2, key3)));
|
|
42482
42503
|
}
|
|
42483
42504
|
async function getMemoryHistory(auth, chainOpts) {
|
|
42484
42505
|
const client = await buildChainClient(chainOpts);
|
|
42485
|
-
const key3 = deriveMemoryKey(auth.privkey);
|
|
42506
|
+
const key3 = await deriveMemoryKey(auth.privkey);
|
|
42486
42507
|
const rows = await client.query("get_agent_memory_history", {
|
|
42487
42508
|
agent_pubkey: auth.pubkey
|
|
42488
42509
|
});
|
|
42489
|
-
return rows.map((r2) => decryptRow(r2, key3));
|
|
42510
|
+
return Promise.all(rows.map((r2) => decryptRow(r2, key3)));
|
|
42490
42511
|
}
|
|
42491
42512
|
async function getMemoryById(id, auth, chainOpts) {
|
|
42492
42513
|
if (!Number.isInteger(id) || id < 1) {
|
|
42493
42514
|
throw new Error("getMemoryById: id must be a positive integer");
|
|
42494
42515
|
}
|
|
42495
42516
|
const client = await buildChainClient(chainOpts);
|
|
42496
|
-
const key3 = deriveMemoryKey(auth.privkey);
|
|
42517
|
+
const key3 = await deriveMemoryKey(auth.privkey);
|
|
42497
42518
|
const row = await client.query("get_agent_memory_by_id", {
|
|
42498
42519
|
agent_pubkey: auth.pubkey,
|
|
42499
42520
|
id
|
|
@@ -42543,7 +42564,10 @@ var DEFAULT_MEMORY_PATH_PATTERNS = [
|
|
|
42543
42564
|
"/.openclaw/memory/",
|
|
42544
42565
|
"/.claude/projects/",
|
|
42545
42566
|
"/memory/",
|
|
42567
|
+
// Also match workspace-relative writes like `memory/2026-07-29.md`.
|
|
42568
|
+
"memory/",
|
|
42546
42569
|
"Memory.md",
|
|
42570
|
+
"DREAMS.md",
|
|
42547
42571
|
"CLAUDE.md",
|
|
42548
42572
|
"AGENTS.md"
|
|
42549
42573
|
];
|
|
@@ -42593,8 +42617,8 @@ function pickContent(toolName, args) {
|
|
|
42593
42617
|
}
|
|
42594
42618
|
return "";
|
|
42595
42619
|
}
|
|
42596
|
-
function matchesMemoryPath(
|
|
42597
|
-
const pLower =
|
|
42620
|
+
function matchesMemoryPath(path6, patterns) {
|
|
42621
|
+
const pLower = path6.toLowerCase();
|
|
42598
42622
|
for (const p of patterns) {
|
|
42599
42623
|
if (p && pLower.includes(p.toLowerCase())) return true;
|
|
42600
42624
|
}
|
|
@@ -42610,13 +42634,13 @@ function classifyMemoryWrite(event, ctx, opts = {}) {
|
|
|
42610
42634
|
const toolNamesLower = toolNames.map((t) => t.toLowerCase());
|
|
42611
42635
|
if (!toolNamesLower.includes(toolNameLower)) return null;
|
|
42612
42636
|
const args = ev.params ?? c.params ?? ev.args ?? c.args ?? ev.arguments ?? c.arguments;
|
|
42613
|
-
const
|
|
42614
|
-
if (!
|
|
42615
|
-
if (!matchesMemoryPath(
|
|
42637
|
+
const path6 = pickPath(args);
|
|
42638
|
+
if (!path6) return null;
|
|
42639
|
+
if (!matchesMemoryPath(path6, patterns)) return null;
|
|
42616
42640
|
const value = pickContent(toolName, args);
|
|
42617
42641
|
if (!value) return null;
|
|
42618
42642
|
return {
|
|
42619
|
-
key:
|
|
42643
|
+
key: path6,
|
|
42620
42644
|
value,
|
|
42621
42645
|
source: `plugin:${toolName}`
|
|
42622
42646
|
};
|
|
@@ -42718,6 +42742,349 @@ async function guardMemoryWrite(input) {
|
|
|
42718
42742
|
};
|
|
42719
42743
|
}
|
|
42720
42744
|
|
|
42745
|
+
// src-ts/memory/sync.ts
|
|
42746
|
+
var MemoryIntegrityError = class extends Error {
|
|
42747
|
+
constructor(id, reason) {
|
|
42748
|
+
super(`memory integrity check failed on id ${id}: ${reason}`);
|
|
42749
|
+
this.id = id;
|
|
42750
|
+
this.name = "MemoryIntegrityError";
|
|
42751
|
+
}
|
|
42752
|
+
id;
|
|
42753
|
+
};
|
|
42754
|
+
var DEFAULT_TTL_MS = 3e4;
|
|
42755
|
+
async function syncLocalMemory(auth, pointer, opts = {}) {
|
|
42756
|
+
const ttl = opts.ttlMs ?? DEFAULT_TTL_MS;
|
|
42757
|
+
const now = Date.now();
|
|
42758
|
+
const withinTtl = !opts.force && now - pointer.checkedAt < ttl;
|
|
42759
|
+
if (withinTtl) {
|
|
42760
|
+
return { drifted: false, pointer };
|
|
42761
|
+
}
|
|
42762
|
+
const currentId = await getActiveMemoryId(auth, opts.chainOpts);
|
|
42763
|
+
const nextPointer = { activeId: currentId, checkedAt: now };
|
|
42764
|
+
if (currentId === pointer.activeId) {
|
|
42765
|
+
return { drifted: false, pointer: nextPointer };
|
|
42766
|
+
}
|
|
42767
|
+
if (currentId === null) {
|
|
42768
|
+
return { drifted: true, current: null, pointer: nextPointer };
|
|
42769
|
+
}
|
|
42770
|
+
const row = await getMemoryById(currentId, auth, opts.chainOpts);
|
|
42771
|
+
if (row.decryptError) {
|
|
42772
|
+
throw new MemoryIntegrityError(currentId, row.decryptError);
|
|
42773
|
+
}
|
|
42774
|
+
return { drifted: true, current: row, pointer: nextPointer };
|
|
42775
|
+
}
|
|
42776
|
+
|
|
42777
|
+
// src-ts/memory/pointer-store.ts
|
|
42778
|
+
import { promises as fs } from "fs";
|
|
42779
|
+
import path3 from "path";
|
|
42780
|
+
var EMPTY = { version: 1, agents: {} };
|
|
42781
|
+
var PointerStore = class {
|
|
42782
|
+
constructor(filePath) {
|
|
42783
|
+
this.filePath = filePath;
|
|
42784
|
+
}
|
|
42785
|
+
filePath;
|
|
42786
|
+
cache = null;
|
|
42787
|
+
loading = null;
|
|
42788
|
+
/** Resolves the pointer for `agentPubkeyHex`, or a zero-pointer that will force a sync on first use. */
|
|
42789
|
+
async get(agentPubkeyHex) {
|
|
42790
|
+
await this.ensureLoaded();
|
|
42791
|
+
return this.cache.agents[agentPubkeyHex] ?? { activeId: null, checkedAt: 0 };
|
|
42792
|
+
}
|
|
42793
|
+
/** Persists an updated pointer. Failures are swallowed to a logger callback (if provided) so sync never blocks the caller. */
|
|
42794
|
+
async set(agentPubkeyHex, pointer, onError) {
|
|
42795
|
+
await this.ensureLoaded();
|
|
42796
|
+
this.cache.agents[agentPubkeyHex] = pointer;
|
|
42797
|
+
try {
|
|
42798
|
+
await this.persist(this.cache);
|
|
42799
|
+
} catch (err) {
|
|
42800
|
+
onError?.(err instanceof Error ? err : new Error(String(err)));
|
|
42801
|
+
}
|
|
42802
|
+
}
|
|
42803
|
+
async ensureLoaded() {
|
|
42804
|
+
if (this.cache) return;
|
|
42805
|
+
if (!this.loading) this.loading = this.loadOnce();
|
|
42806
|
+
await this.loading;
|
|
42807
|
+
}
|
|
42808
|
+
async loadOnce() {
|
|
42809
|
+
try {
|
|
42810
|
+
const raw2 = await fs.readFile(this.filePath, "utf8");
|
|
42811
|
+
const parsed = JSON.parse(raw2);
|
|
42812
|
+
if (parsed && parsed.version === 1 && parsed.agents && typeof parsed.agents === "object") {
|
|
42813
|
+
this.cache = parsed;
|
|
42814
|
+
return;
|
|
42815
|
+
}
|
|
42816
|
+
} catch {
|
|
42817
|
+
}
|
|
42818
|
+
this.cache = { ...EMPTY, agents: {} };
|
|
42819
|
+
}
|
|
42820
|
+
async persist(file) {
|
|
42821
|
+
await fs.mkdir(path3.dirname(this.filePath), { recursive: true });
|
|
42822
|
+
const tmp = `${this.filePath}.${process.pid}.tmp`;
|
|
42823
|
+
await fs.writeFile(tmp, JSON.stringify(file, null, 2), "utf8");
|
|
42824
|
+
await fs.rename(tmp, this.filePath);
|
|
42825
|
+
}
|
|
42826
|
+
};
|
|
42827
|
+
function defaultPointerPath(workspaceDir = process.cwd()) {
|
|
42828
|
+
return path3.join(workspaceDir, ".atbash", "memory-pointer.json");
|
|
42829
|
+
}
|
|
42830
|
+
|
|
42831
|
+
// src-ts/memory/file-logger.ts
|
|
42832
|
+
import { promises as fs2 } from "fs";
|
|
42833
|
+
import path4 from "path";
|
|
42834
|
+
function formatMeta(meta) {
|
|
42835
|
+
if (!meta || Object.keys(meta).length === 0) return "";
|
|
42836
|
+
try {
|
|
42837
|
+
return " " + JSON.stringify(meta);
|
|
42838
|
+
} catch {
|
|
42839
|
+
return "";
|
|
42840
|
+
}
|
|
42841
|
+
}
|
|
42842
|
+
function createFileLogger(filePath, upstream) {
|
|
42843
|
+
let queue = Promise.resolve();
|
|
42844
|
+
async function ensureDir() {
|
|
42845
|
+
await fs2.mkdir(path4.dirname(filePath), { recursive: true });
|
|
42846
|
+
}
|
|
42847
|
+
function append(level, message, meta) {
|
|
42848
|
+
const line = `${(/* @__PURE__ */ new Date()).toISOString()} [${level}] ${message}${formatMeta(meta)}
|
|
42849
|
+
`;
|
|
42850
|
+
queue = queue.then(ensureDir).then(() => fs2.appendFile(filePath, line, "utf8")).catch(() => {
|
|
42851
|
+
});
|
|
42852
|
+
}
|
|
42853
|
+
return {
|
|
42854
|
+
info(message, meta) {
|
|
42855
|
+
upstream?.info(message, meta ?? {});
|
|
42856
|
+
append("info", message, meta);
|
|
42857
|
+
},
|
|
42858
|
+
warn(message, meta) {
|
|
42859
|
+
upstream?.warn(message, meta ?? {});
|
|
42860
|
+
append("warn", message, meta);
|
|
42861
|
+
}
|
|
42862
|
+
};
|
|
42863
|
+
}
|
|
42864
|
+
function defaultPluginLogPath(workspaceDir = process.cwd()) {
|
|
42865
|
+
return path4.join(workspaceDir, ".atbash", "plugin.log");
|
|
42866
|
+
}
|
|
42867
|
+
|
|
42868
|
+
// src-ts/memory/read-classifier.ts
|
|
42869
|
+
var DEFAULT_MEMORY_READ_TOOL_NAMES = [
|
|
42870
|
+
"memory_search",
|
|
42871
|
+
"memory_get"
|
|
42872
|
+
];
|
|
42873
|
+
var DEFAULT_READ_TOOL_NAMES = [
|
|
42874
|
+
"read",
|
|
42875
|
+
"read_file"
|
|
42876
|
+
];
|
|
42877
|
+
function extractToolName(event, ctx) {
|
|
42878
|
+
const ev = event ?? {};
|
|
42879
|
+
const c = ctx ?? {};
|
|
42880
|
+
return (ev.toolName ?? c.tool?.name ?? c.toolName ?? c.name ?? "").toString();
|
|
42881
|
+
}
|
|
42882
|
+
function extractPath(event, ctx) {
|
|
42883
|
+
const ev = event ?? {};
|
|
42884
|
+
const c = ctx ?? {};
|
|
42885
|
+
const args = ev.args ?? ev.params ?? ev.arguments ?? c.args ?? c.params ?? {};
|
|
42886
|
+
for (const k of ["path", "file_path", "filePath", "target", "file"]) {
|
|
42887
|
+
const v = args[k];
|
|
42888
|
+
if (typeof v === "string" && v.length > 0) return v;
|
|
42889
|
+
}
|
|
42890
|
+
return "";
|
|
42891
|
+
}
|
|
42892
|
+
function matchesMemoryPath2(path6, patterns) {
|
|
42893
|
+
const p = path6.toLowerCase();
|
|
42894
|
+
for (const pat of patterns) {
|
|
42895
|
+
if (pat && p.includes(pat.toLowerCase())) return true;
|
|
42896
|
+
}
|
|
42897
|
+
return false;
|
|
42898
|
+
}
|
|
42899
|
+
function classifyMemoryRead(event, ctx, opts = {}) {
|
|
42900
|
+
const toolName = extractToolName(event, ctx).toLowerCase();
|
|
42901
|
+
if (!toolName) return false;
|
|
42902
|
+
const readTools = new Set(
|
|
42903
|
+
(opts.readToolNames ?? DEFAULT_MEMORY_READ_TOOL_NAMES).map((s2) => s2.toLowerCase())
|
|
42904
|
+
);
|
|
42905
|
+
if (readTools.has(toolName)) return true;
|
|
42906
|
+
const genericReadTools = new Set(
|
|
42907
|
+
(opts.genericReadToolNames ?? DEFAULT_READ_TOOL_NAMES).map((s2) => s2.toLowerCase())
|
|
42908
|
+
);
|
|
42909
|
+
if (genericReadTools.has(toolName)) {
|
|
42910
|
+
const path6 = extractPath(event, ctx);
|
|
42911
|
+
if (!path6) return false;
|
|
42912
|
+
const patterns = opts.patterns ? [...DEFAULT_MEMORY_PATH_PATTERNS, ...opts.patterns] : DEFAULT_MEMORY_PATH_PATTERNS;
|
|
42913
|
+
return matchesMemoryPath2(path6, patterns);
|
|
42914
|
+
}
|
|
42915
|
+
return false;
|
|
42916
|
+
}
|
|
42917
|
+
|
|
42918
|
+
// src-ts/memory/guard-manager.ts
|
|
42919
|
+
import { promises as fs3 } from "fs";
|
|
42920
|
+
import path5 from "path";
|
|
42921
|
+
var DEFAULT_SYNC_TTL_MS = 3e4;
|
|
42922
|
+
var MemoryGuardManager = class {
|
|
42923
|
+
constructor(opts) {
|
|
42924
|
+
this.opts = opts;
|
|
42925
|
+
const workspaceDir = opts.workspaceDir;
|
|
42926
|
+
this.memoryFilePath = opts.memoryFilePath ?? path5.join(workspaceDir, "MEMORY.md");
|
|
42927
|
+
this.pointerStore = new PointerStore(opts.pointerFilePath ?? defaultPointerPath(workspaceDir));
|
|
42928
|
+
this.logger = createFileLogger(
|
|
42929
|
+
opts.logFilePath ?? defaultPluginLogPath(workspaceDir),
|
|
42930
|
+
opts.hostLogger
|
|
42931
|
+
);
|
|
42932
|
+
this.ttlMs = opts.ttlMs ?? DEFAULT_SYNC_TTL_MS;
|
|
42933
|
+
this.rollbackMinScore = opts.rollbackMinScore ?? 1;
|
|
42934
|
+
this.enforce = opts.enforce !== false;
|
|
42935
|
+
this.agentPubkeyHex = opts.auth.pubkey;
|
|
42936
|
+
this.logger.info(
|
|
42937
|
+
`[atbash] guard manager ready \u2014 agent=${this.agentPubkeyHex.slice(0, 16)}\u2026 org=${opts.orgName ?? "(none)"} memoryFilePath=${this.memoryFilePath} ttl=${this.ttlMs}ms minScore=${this.rollbackMinScore}`
|
|
42938
|
+
);
|
|
42939
|
+
}
|
|
42940
|
+
opts;
|
|
42941
|
+
pointerStore;
|
|
42942
|
+
logger;
|
|
42943
|
+
memoryFilePath;
|
|
42944
|
+
ttlMs;
|
|
42945
|
+
rollbackMinScore;
|
|
42946
|
+
enforce;
|
|
42947
|
+
agentPubkeyHex;
|
|
42948
|
+
/**
|
|
42949
|
+
* One-shot chain probe at plugin registration. Refreshes MEMORY.md
|
|
42950
|
+
* from chain when drifted and score passes threshold. Fire-and-forget
|
|
42951
|
+
* — errors are logged, never thrown.
|
|
42952
|
+
*/
|
|
42953
|
+
async runBootProbe() {
|
|
42954
|
+
try {
|
|
42955
|
+
const seed = { activeId: null, checkedAt: 0 };
|
|
42956
|
+
const result = await syncLocalMemory(this.opts.auth, seed, { ttlMs: 0, force: true });
|
|
42957
|
+
if (!result.drifted && result.pointer.activeId == null) {
|
|
42958
|
+
this.logger.info(
|
|
42959
|
+
`[atbash] no active memory on chain for agent=${this.agentPubkeyHex.slice(0, 16)}\u2026 org=${this.opts.orgName ?? "(none)"} \u2014 either the agent isn't registered on this chain or hasn't written any memory. Sync will remain a no-op until a write lands.`
|
|
42960
|
+
);
|
|
42961
|
+
} else if (result.drifted && result.current) {
|
|
42962
|
+
if (result.current.score < this.rollbackMinScore) {
|
|
42963
|
+
this.logger.warn(
|
|
42964
|
+
`[atbash] boot sync REFUSED refresh \u2014 id=${result.current.id} score=${result.current.score} below threshold ${this.rollbackMinScore}. Leaving MEMORY.md and pointer untouched; next memory read will be blocked.`
|
|
42965
|
+
);
|
|
42966
|
+
return;
|
|
42967
|
+
}
|
|
42968
|
+
this.logger.info(
|
|
42969
|
+
`[atbash] boot sync: refreshing local memory \u2014 id=${result.current.id} score=${result.current.score}`
|
|
42970
|
+
);
|
|
42971
|
+
try {
|
|
42972
|
+
await this.writeMemoryAtomic(result.current.content);
|
|
42973
|
+
} catch (err) {
|
|
42974
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
42975
|
+
this.logger.warn("[atbash] boot sync write failed (serving whatever's on disk)", { error: msg });
|
|
42976
|
+
}
|
|
42977
|
+
}
|
|
42978
|
+
await this.pointerStore.set(this.agentPubkeyHex, result.pointer);
|
|
42979
|
+
} catch (err) {
|
|
42980
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
42981
|
+
this.logger.warn("[atbash] boot memory sync failed \u2014 check chain endpoint / orgName", { error: msg });
|
|
42982
|
+
}
|
|
42983
|
+
}
|
|
42984
|
+
/**
|
|
42985
|
+
* Returns a `HookDecision` when the event is a memory read or write
|
|
42986
|
+
* (host returns it verbatim to its runtime). Returns `null` when the
|
|
42987
|
+
* event isn't memory-related — host falls through to its own audit.
|
|
42988
|
+
*/
|
|
42989
|
+
async handleBeforeToolCall(event, ctx) {
|
|
42990
|
+
if (classifyMemoryRead(event, ctx, this.opts.memoryReadClassifier)) {
|
|
42991
|
+
this.logger.info("[atbash] memory read intercepted \u2014 running sync check");
|
|
42992
|
+
return this.handleMemoryRead();
|
|
42993
|
+
}
|
|
42994
|
+
const guardLogger = {
|
|
42995
|
+
info: (msg, meta) => this.logger.info(msg, meta && typeof meta === "object" ? meta : void 0),
|
|
42996
|
+
warn: (msg, meta) => this.logger.warn(msg, meta && typeof meta === "object" ? meta : void 0)
|
|
42997
|
+
};
|
|
42998
|
+
const guard = await guardMemoryWrite({
|
|
42999
|
+
event,
|
|
43000
|
+
ctx,
|
|
43001
|
+
auth: this.opts.auth,
|
|
43002
|
+
endpoint: this.opts.judgeEndpoint,
|
|
43003
|
+
verifyPubKey: this.opts.judgeVerifyPubKey,
|
|
43004
|
+
orgName: this.opts.orgName,
|
|
43005
|
+
patterns: this.opts.memoryPathPatterns,
|
|
43006
|
+
toolNames: this.opts.memoryWriteToolNames,
|
|
43007
|
+
enforce: this.enforce,
|
|
43008
|
+
debug: this.opts.debug,
|
|
43009
|
+
logger: guardLogger
|
|
43010
|
+
});
|
|
43011
|
+
return this.mapGuardResult(guard);
|
|
43012
|
+
}
|
|
43013
|
+
mapGuardResult(guard) {
|
|
43014
|
+
if (!guard.handled) return null;
|
|
43015
|
+
const d = guard.decision;
|
|
43016
|
+
const sr2 = guard.scanResult;
|
|
43017
|
+
const verdict = sr2?.verdict ?? "?";
|
|
43018
|
+
const score = sr2?.score ?? "?";
|
|
43019
|
+
if (d.block) {
|
|
43020
|
+
this.logger.warn(
|
|
43021
|
+
`[atbash] guardMemoryWrite BLOCKED \u2014 verdict=${verdict} score=${score} reason=${(d.reason ?? "").slice(0, 200)}`
|
|
43022
|
+
);
|
|
43023
|
+
return {
|
|
43024
|
+
block: true,
|
|
43025
|
+
blockReason: d.reason ?? "",
|
|
43026
|
+
allow: false,
|
|
43027
|
+
reason: d.reason
|
|
43028
|
+
};
|
|
43029
|
+
}
|
|
43030
|
+
this.logger.info(
|
|
43031
|
+
`[atbash] guardMemoryWrite ALLOWED \u2014 verdict=${verdict} score=${score} committed=${guard.committed === true}`
|
|
43032
|
+
);
|
|
43033
|
+
return { allow: true };
|
|
43034
|
+
}
|
|
43035
|
+
async handleMemoryRead() {
|
|
43036
|
+
const pointer = await this.pointerStore.get(this.agentPubkeyHex);
|
|
43037
|
+
let result;
|
|
43038
|
+
try {
|
|
43039
|
+
result = await syncLocalMemory(this.opts.auth, pointer, { ttlMs: this.ttlMs });
|
|
43040
|
+
} catch (err) {
|
|
43041
|
+
if (err instanceof MemoryIntegrityError) {
|
|
43042
|
+
const reason = `Memory integrity check failed on id ${err.id} \u2014 read blocked.`;
|
|
43043
|
+
this.logger.warn("[atbash] MEMORY INTEGRITY FAILURE", { id: err.id, error: err.message });
|
|
43044
|
+
if (!this.enforce) return null;
|
|
43045
|
+
return { block: true, blockReason: reason, allow: false, reason };
|
|
43046
|
+
}
|
|
43047
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
43048
|
+
this.logger.warn("[atbash] memory sync failed (serving local copy)", { error: msg });
|
|
43049
|
+
return null;
|
|
43050
|
+
}
|
|
43051
|
+
if (result.drifted) {
|
|
43052
|
+
const fresh = result.current;
|
|
43053
|
+
if (fresh) {
|
|
43054
|
+
if (fresh.score < this.rollbackMinScore) {
|
|
43055
|
+
const reason = `Rolled-back memory version #${fresh.id} scored ${fresh.score} (below threshold ${this.rollbackMinScore}) \u2014 read blocked.`;
|
|
43056
|
+
this.logger.warn("[atbash] blocking read on low-score rollback", { id: fresh.id, score: fresh.score });
|
|
43057
|
+
if (!this.enforce) return null;
|
|
43058
|
+
return { block: true, blockReason: reason, allow: false, reason };
|
|
43059
|
+
}
|
|
43060
|
+
this.logger.info("[atbash] memory drift detected \u2014 refreshing local file", {
|
|
43061
|
+
id: fresh.id,
|
|
43062
|
+
score: fresh.score
|
|
43063
|
+
});
|
|
43064
|
+
try {
|
|
43065
|
+
await this.writeMemoryAtomic(fresh.content);
|
|
43066
|
+
} catch (err) {
|
|
43067
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
43068
|
+
this.logger.warn("[atbash] failed to write refreshed memory (serving old)", { error: msg });
|
|
43069
|
+
}
|
|
43070
|
+
} else {
|
|
43071
|
+
this.logger.info("[atbash] active memory removed on chain", { pubkey: this.agentPubkeyHex });
|
|
43072
|
+
}
|
|
43073
|
+
}
|
|
43074
|
+
await this.pointerStore.set(this.agentPubkeyHex, result.pointer);
|
|
43075
|
+
return null;
|
|
43076
|
+
}
|
|
43077
|
+
async writeMemoryAtomic(content) {
|
|
43078
|
+
await fs3.mkdir(path5.dirname(this.memoryFilePath), { recursive: true });
|
|
43079
|
+
const tmp = `${this.memoryFilePath}.${process.pid}.tmp`;
|
|
43080
|
+
await fs3.writeFile(tmp, content, "utf8");
|
|
43081
|
+
await fs3.rename(tmp, this.memoryFilePath);
|
|
43082
|
+
}
|
|
43083
|
+
};
|
|
43084
|
+
function createMemoryGuardManager(opts) {
|
|
43085
|
+
return new MemoryGuardManager(opts);
|
|
43086
|
+
}
|
|
43087
|
+
|
|
42721
43088
|
// src-ts/index.ts
|
|
42722
43089
|
function isValidPrivateKey(hex) {
|
|
42723
43090
|
return native.isValidPrivateKey(hex);
|
|
@@ -42780,14 +43147,23 @@ export {
|
|
|
42780
43147
|
DEFAULT_CHROMIA_NODE_URLS,
|
|
42781
43148
|
DEFAULT_ENDPOINT,
|
|
42782
43149
|
DEFAULT_MEMORY_PATH_PATTERNS,
|
|
43150
|
+
DEFAULT_MEMORY_READ_TOOL_NAMES,
|
|
42783
43151
|
DEFAULT_MEMORY_WRITE_TOOL_NAMES,
|
|
43152
|
+
MemoryGuardManager,
|
|
43153
|
+
MemoryIntegrityError,
|
|
43154
|
+
PointerStore,
|
|
42784
43155
|
SignatureVerificationError,
|
|
43156
|
+
classifyMemoryRead,
|
|
42785
43157
|
classifyMemoryWrite,
|
|
42786
43158
|
commitMemoryVersion,
|
|
42787
43159
|
containsEvasionCharacters,
|
|
42788
43160
|
containsSecret,
|
|
43161
|
+
createFileLogger,
|
|
43162
|
+
createMemoryGuardManager,
|
|
42789
43163
|
createMemorySnapshot,
|
|
42790
43164
|
decryptMemoryContent,
|
|
43165
|
+
defaultPluginLogPath,
|
|
43166
|
+
defaultPointerPath,
|
|
42791
43167
|
deriveMemoryKey,
|
|
42792
43168
|
derivePublicKey,
|
|
42793
43169
|
diffMemorySnapshots,
|
|
@@ -42795,6 +43171,7 @@ export {
|
|
|
42795
43171
|
flushTelemetry,
|
|
42796
43172
|
generateKeypair,
|
|
42797
43173
|
getActiveMemory,
|
|
43174
|
+
getActiveMemoryId,
|
|
42798
43175
|
getAllAgentMemory,
|
|
42799
43176
|
getConfigDir,
|
|
42800
43177
|
getConfigPath,
|
|
@@ -42824,6 +43201,7 @@ export {
|
|
|
42824
43201
|
shutdownTelemetry,
|
|
42825
43202
|
signJudgeAction,
|
|
42826
43203
|
signLogToolCall,
|
|
43204
|
+
syncLocalMemory,
|
|
42827
43205
|
validateJudgeEndpoint,
|
|
42828
43206
|
verifyJudgeResponseSignature,
|
|
42829
43207
|
verifySignature
|