@atbash/sdk 0.7.0 → 0.7.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 +118 -2
- package/dist/browser.mjs +350 -33
- package/dist/browser.mjs.map +1 -1
- package/dist/index.d.mts +118 -2
- package/dist/index.d.ts +118 -2
- package/dist/index.js +242 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +239 -34
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
package/dist/index.mjs
CHANGED
|
@@ -3046,24 +3046,97 @@ var HttpClient = class {
|
|
|
3046
3046
|
});
|
|
3047
3047
|
}
|
|
3048
3048
|
async fetch(url, init4) {
|
|
3049
|
-
|
|
3049
|
+
try {
|
|
3050
|
+
return await fetch(url, {
|
|
3051
|
+
...init4,
|
|
3052
|
+
signal: AbortSignal.timeout(this.timeoutMs)
|
|
3053
|
+
});
|
|
3054
|
+
} catch (err) {
|
|
3055
|
+
throw classifyTransportError(err, url, init4.method ?? "GET", this.timeoutMs);
|
|
3056
|
+
}
|
|
3050
3057
|
}
|
|
3051
3058
|
};
|
|
3059
|
+
var HttpTransportError = class extends Error {
|
|
3060
|
+
kind;
|
|
3061
|
+
constructor(kind, message, options) {
|
|
3062
|
+
super(message, options);
|
|
3063
|
+
this.name = "HttpTransportError";
|
|
3064
|
+
this.kind = kind;
|
|
3065
|
+
}
|
|
3066
|
+
};
|
|
3067
|
+
function classifyTransportError(err, url, method, timeoutMs) {
|
|
3068
|
+
const name2 = err instanceof Error ? err.name : "";
|
|
3069
|
+
const cause = err instanceof Error ? err.cause : void 0;
|
|
3070
|
+
const code2 = cause && typeof cause === "object" && "code" in cause ? String(cause.code) : "";
|
|
3071
|
+
if (name2 === "TimeoutError") {
|
|
3072
|
+
return new HttpTransportError(
|
|
3073
|
+
"timeout",
|
|
3074
|
+
`${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`,
|
|
3075
|
+
{ cause: err }
|
|
3076
|
+
);
|
|
3077
|
+
}
|
|
3078
|
+
if (name2 === "AbortError") {
|
|
3079
|
+
return new HttpTransportError(
|
|
3080
|
+
"aborted",
|
|
3081
|
+
`${method} ${url} was cancelled by the caller`,
|
|
3082
|
+
{ cause: err }
|
|
3083
|
+
);
|
|
3084
|
+
}
|
|
3085
|
+
if (code2 === "ENOTFOUND" || code2 === "EAI_AGAIN") {
|
|
3086
|
+
return new HttpTransportError(
|
|
3087
|
+
"dns",
|
|
3088
|
+
`could not resolve the judge hostname (${url}) \u2014 check the endpoint and DNS`,
|
|
3089
|
+
{ cause: err }
|
|
3090
|
+
);
|
|
3091
|
+
}
|
|
3092
|
+
if (code2 === "ECONNREFUSED") {
|
|
3093
|
+
return new HttpTransportError(
|
|
3094
|
+
"connect_refused",
|
|
3095
|
+
`judge refused the connection (${url}) \u2014 the service may be down or restarting`,
|
|
3096
|
+
{ cause: err }
|
|
3097
|
+
);
|
|
3098
|
+
}
|
|
3099
|
+
if (code2 === "ECONNRESET" || code2 === "EPIPE") {
|
|
3100
|
+
return new HttpTransportError(
|
|
3101
|
+
"connection_reset",
|
|
3102
|
+
`judge dropped the connection mid-request (${url}) \u2014 retry once`,
|
|
3103
|
+
{ cause: err }
|
|
3104
|
+
);
|
|
3105
|
+
}
|
|
3106
|
+
return new HttpTransportError(
|
|
3107
|
+
"unknown",
|
|
3108
|
+
`${method} ${url} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
3109
|
+
{ cause: err }
|
|
3110
|
+
);
|
|
3111
|
+
}
|
|
3052
3112
|
|
|
3053
3113
|
// src-ts/keyLoader.ts
|
|
3054
|
-
import { readFileSync } from "fs";
|
|
3114
|
+
import { existsSync, readFileSync } from "fs";
|
|
3115
|
+
|
|
3116
|
+
// src-ts/key-path.ts
|
|
3055
3117
|
import { homedir } from "os";
|
|
3056
3118
|
import { join } from "path";
|
|
3057
|
-
var
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
return join(home, DEFAULT_KEY_PATH_REL);
|
|
3119
|
+
var KEY_DIR_REL = ".config/atbash";
|
|
3120
|
+
var KEY_FILENAMES = ["guard-client-key", "atbash-client-key"];
|
|
3121
|
+
function home() {
|
|
3122
|
+
return process.env.HOME || homedir() || "";
|
|
3062
3123
|
}
|
|
3063
3124
|
function expandHome(p) {
|
|
3064
3125
|
if (!p.startsWith("~/")) return p;
|
|
3065
|
-
|
|
3066
|
-
|
|
3126
|
+
return join(home(), p.slice(2));
|
|
3127
|
+
}
|
|
3128
|
+
function keyPathCandidates() {
|
|
3129
|
+
return KEY_FILENAMES.map((name2) => join(home(), KEY_DIR_REL, name2));
|
|
3130
|
+
}
|
|
3131
|
+
function chooseKeyPath(input, exists) {
|
|
3132
|
+
if (input) return expandHome(input);
|
|
3133
|
+
const candidates = keyPathCandidates();
|
|
3134
|
+
return candidates.find(exists) ?? candidates[0];
|
|
3135
|
+
}
|
|
3136
|
+
|
|
3137
|
+
// src-ts/keyLoader.ts
|
|
3138
|
+
function resolveKeyPath(input) {
|
|
3139
|
+
return chooseKeyPath(input, existsSync);
|
|
3067
3140
|
}
|
|
3068
3141
|
function readKeyFile(keyPath) {
|
|
3069
3142
|
const content = String(readFileSync(keyPath, "utf8") || "").trim();
|
|
@@ -3093,6 +3166,12 @@ function readKeyFile(keyPath) {
|
|
|
3093
3166
|
}
|
|
3094
3167
|
function loadAgentFromFile(keyPath) {
|
|
3095
3168
|
const resolved = resolveKeyPath(keyPath);
|
|
3169
|
+
if (!existsSync(resolved)) {
|
|
3170
|
+
const looked = keyPath ? [resolved] : keyPathCandidates();
|
|
3171
|
+
throw new Error(
|
|
3172
|
+
`atbash key file not found. Looked for: ${looked.join(", ")}`
|
|
3173
|
+
);
|
|
3174
|
+
}
|
|
3096
3175
|
const { privKey } = readKeyFile(resolved);
|
|
3097
3176
|
return native.loadAgent(privKey);
|
|
3098
3177
|
}
|
|
@@ -3138,8 +3217,8 @@ var durationHistogram = null;
|
|
|
3138
3217
|
var defaultSource = "sdk";
|
|
3139
3218
|
function isTelemetryOptedOut() {
|
|
3140
3219
|
try {
|
|
3141
|
-
const
|
|
3142
|
-
const filePath = join2(
|
|
3220
|
+
const home2 = process.env.HOME || homedir2() || "";
|
|
3221
|
+
const filePath = join2(home2, ".config", "atbash", "telemetry.json");
|
|
3143
3222
|
const raw2 = readFileSync2(filePath, "utf-8").trim();
|
|
3144
3223
|
if (!raw2) return false;
|
|
3145
3224
|
const config2 = JSON.parse(raw2);
|
|
@@ -3217,7 +3296,7 @@ async function shutdownTelemetry() {
|
|
|
3217
3296
|
// src-ts/userConfig.ts
|
|
3218
3297
|
import {
|
|
3219
3298
|
chmodSync,
|
|
3220
|
-
existsSync,
|
|
3299
|
+
existsSync as existsSync2,
|
|
3221
3300
|
mkdirSync,
|
|
3222
3301
|
readFileSync as readFileSync3,
|
|
3223
3302
|
writeFileSync
|
|
@@ -3230,11 +3309,12 @@ var ENV_MAP = {
|
|
|
3230
3309
|
judgeEndpoint: "ATBASH_ENDPOINT",
|
|
3231
3310
|
blockchainRid: "ATBASH_BLOCKCHAIN_RID",
|
|
3232
3311
|
provider: "ATBASH_PROVIDER",
|
|
3233
|
-
providerModel: "ATBASH_PROVIDER_MODEL"
|
|
3312
|
+
providerModel: "ATBASH_PROVIDER_MODEL",
|
|
3313
|
+
debug: "ATBASH_DEBUG"
|
|
3234
3314
|
};
|
|
3235
3315
|
function getConfigDir() {
|
|
3236
|
-
const
|
|
3237
|
-
return join3(
|
|
3316
|
+
const home2 = process.env.HOME || homedir3() || "";
|
|
3317
|
+
return join3(home2, ".config", "atbash");
|
|
3238
3318
|
}
|
|
3239
3319
|
function getConfigPath() {
|
|
3240
3320
|
return join3(getConfigDir(), "config.json");
|
|
@@ -3242,7 +3322,7 @@ function getConfigPath() {
|
|
|
3242
3322
|
function loadUserConfig() {
|
|
3243
3323
|
try {
|
|
3244
3324
|
const p = getConfigPath();
|
|
3245
|
-
if (!
|
|
3325
|
+
if (!existsSync2(p)) return {};
|
|
3246
3326
|
const raw2 = readFileSync3(p, "utf-8").trim();
|
|
3247
3327
|
if (!raw2) return {};
|
|
3248
3328
|
return JSON.parse(raw2);
|
|
@@ -3253,7 +3333,7 @@ function loadUserConfig() {
|
|
|
3253
3333
|
}
|
|
3254
3334
|
function saveUserConfig(config2) {
|
|
3255
3335
|
const dir = getConfigDir();
|
|
3256
|
-
if (!
|
|
3336
|
+
if (!existsSync2(dir)) {
|
|
3257
3337
|
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
3258
3338
|
}
|
|
3259
3339
|
const filePath = getConfigPath();
|
|
@@ -3293,6 +3373,7 @@ var Atbash = class _Atbash {
|
|
|
3293
3373
|
failClosed;
|
|
3294
3374
|
/** Org key learned from the last agent-exists check, for this agent only. */
|
|
3295
3375
|
_orgKeyFromChain = null;
|
|
3376
|
+
debug;
|
|
3296
3377
|
logger;
|
|
3297
3378
|
http;
|
|
3298
3379
|
/**
|
|
@@ -3306,6 +3387,8 @@ var Atbash = class _Atbash {
|
|
|
3306
3387
|
* server-side replay protection windows never expire it mid-session.
|
|
3307
3388
|
*/
|
|
3308
3389
|
_authBearer = null;
|
|
3390
|
+
/** Guards `logEnvironmentOnce` — hosts construct several clients. */
|
|
3391
|
+
static environmentLogged = false;
|
|
3309
3392
|
constructor(privkey, options = {}) {
|
|
3310
3393
|
this.auth = native.loadAgent(privkey);
|
|
3311
3394
|
this.endpoint = (options.endpoint ?? DEFAULT_ENDPOINT).replace(/\/+$/, "") || DEFAULT_ENDPOINT;
|
|
@@ -3315,8 +3398,10 @@ var Atbash = class _Atbash {
|
|
|
3315
3398
|
this.verifyPubKey = options.verifyPubKey;
|
|
3316
3399
|
this.orgEncryptionPubKey = options.orgEncryptionPubKey;
|
|
3317
3400
|
this.failClosed = options.failClosed !== false;
|
|
3401
|
+
this.debug = options.debug === true;
|
|
3318
3402
|
this.logger = options.logger ?? {};
|
|
3319
|
-
this.http = new HttpClient(this.endpoint, options.timeoutMs ??
|
|
3403
|
+
this.http = new HttpClient(this.endpoint, options.timeoutMs ?? 6e4);
|
|
3404
|
+
this.logEnvironmentOnce();
|
|
3320
3405
|
if (this.endpoint !== DEFAULT_ENDPOINT) {
|
|
3321
3406
|
this.logger.warn?.("[atbash] running on non-default judge endpoint", {
|
|
3322
3407
|
endpoint: this.endpoint,
|
|
@@ -3324,6 +3409,31 @@ var Atbash = class _Atbash {
|
|
|
3324
3409
|
});
|
|
3325
3410
|
}
|
|
3326
3411
|
}
|
|
3412
|
+
/**
|
|
3413
|
+
* Say which environment this build talks to, once per process.
|
|
3414
|
+
*
|
|
3415
|
+
* The endpoint and both chain RIDs are compiled in, chosen by the npm tag,
|
|
3416
|
+
* and no configuration repoints a released build. So installing the build
|
|
3417
|
+
* for the wrong environment is invisible: the plugin loads, the hook fires,
|
|
3418
|
+
* and every judge call fails because the agent does not exist on the chain
|
|
3419
|
+
* this build targets. Organisation names are not unique across environments
|
|
3420
|
+
* either, so an org resolving is not evidence the build is right.
|
|
3421
|
+
*/
|
|
3422
|
+
logEnvironmentOnce() {
|
|
3423
|
+
if (_Atbash.environmentLogged) return;
|
|
3424
|
+
_Atbash.environmentLogged = true;
|
|
3425
|
+
const brief = (rid) => rid ? `${rid.slice(0, 8)}\u2026` : "(unset)";
|
|
3426
|
+
this.logger.info?.(
|
|
3427
|
+
`[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"}`,
|
|
3428
|
+
{
|
|
3429
|
+
judgeEndpoint: this.endpoint,
|
|
3430
|
+
publicBlockchainRid: native.DEFAULT_BLOCKCHAIN_RID,
|
|
3431
|
+
privateBlockchainRid: native.DEFAULT_PRIVATE_BLOCKCHAIN_RID,
|
|
3432
|
+
activeBlockchainRid: this.blockchainRid,
|
|
3433
|
+
responseSignatureCheck: Boolean(this.verifyPubKey)
|
|
3434
|
+
}
|
|
3435
|
+
);
|
|
3436
|
+
}
|
|
3327
3437
|
/**
|
|
3328
3438
|
* Construct from resolved config: explicit overrides → env vars → the
|
|
3329
3439
|
* `~/.config/atbash/config.json` file (see userConfig.resolve). The private
|
|
@@ -3347,6 +3457,9 @@ var Atbash = class _Atbash {
|
|
|
3347
3457
|
orgName: options.orgName,
|
|
3348
3458
|
verifyPubKey: validated.verifyPubKey ?? void 0,
|
|
3349
3459
|
failClosed: options.failClosed,
|
|
3460
|
+
// ATBASH_DEBUG lets an operator turn diagnostics on without editing a
|
|
3461
|
+
// host's plugin config, which is usually the harder half.
|
|
3462
|
+
debug: options.debug ?? /^(1|true|yes)$/i.test(resolve("debug")),
|
|
3350
3463
|
logger: options.logger
|
|
3351
3464
|
});
|
|
3352
3465
|
}
|
|
@@ -3446,11 +3559,15 @@ var Atbash = class _Atbash {
|
|
|
3446
3559
|
* response bytes via the Rust core's `verifySignature`.
|
|
3447
3560
|
*/
|
|
3448
3561
|
async judgeAction(action, context = "", options = {}) {
|
|
3449
|
-
return this.track(
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3562
|
+
return this.track("judgeAction", this.auth.pubkey, async () => {
|
|
3563
|
+
try {
|
|
3564
|
+
return await this._judgeAction(action, context, options);
|
|
3565
|
+
} catch (err) {
|
|
3566
|
+
if (!isEncryptionStateMismatch(err)) throw err;
|
|
3567
|
+
this._orgKeyFromChain = null;
|
|
3568
|
+
return await this._judgeAction(action, context, options);
|
|
3569
|
+
}
|
|
3570
|
+
});
|
|
3454
3571
|
}
|
|
3455
3572
|
async _judgeAction(action, context, options) {
|
|
3456
3573
|
if (!action?.trim()) {
|
|
@@ -3588,8 +3705,9 @@ var Atbash = class _Atbash {
|
|
|
3588
3705
|
});
|
|
3589
3706
|
if (result.verdict === "No verdict") {
|
|
3590
3707
|
if (result.status !== "logged") {
|
|
3591
|
-
return this.
|
|
3708
|
+
return this.failJudge(
|
|
3592
3709
|
`judge returned no verdict without an audit-tier marker (status: ${result.status || "absent"})`,
|
|
3710
|
+
void 0,
|
|
3593
3711
|
result.toolCallId
|
|
3594
3712
|
);
|
|
3595
3713
|
}
|
|
@@ -3641,16 +3759,38 @@ var Atbash = class _Atbash {
|
|
|
3641
3759
|
toolCallId: result.toolCallId
|
|
3642
3760
|
};
|
|
3643
3761
|
}
|
|
3644
|
-
return this.
|
|
3762
|
+
return this.failJudge(
|
|
3645
3763
|
"unrecognized action_type from judge",
|
|
3764
|
+
void 0,
|
|
3646
3765
|
result.toolCallId
|
|
3647
3766
|
);
|
|
3648
3767
|
} catch (err) {
|
|
3649
|
-
|
|
3650
|
-
this.logger.warn?.("[atbash] judge API failed", { reason: message });
|
|
3651
|
-
return this.fail(message);
|
|
3768
|
+
return this.failJudge(errorMessage(err), err);
|
|
3652
3769
|
}
|
|
3653
3770
|
}
|
|
3771
|
+
/**
|
|
3772
|
+
* One exit for every judge failure.
|
|
3773
|
+
*
|
|
3774
|
+
* Status and reason go in the *message*, not only in the meta object: hosts
|
|
3775
|
+
* print the message and drop the meta, which is why this read as a bare
|
|
3776
|
+
* "judge API failed" while the judge was answering with a precise reason.
|
|
3777
|
+
* The response body follows only under `debug`, since it can echo the action.
|
|
3778
|
+
*/
|
|
3779
|
+
failJudge(reason, cause, toolCallId) {
|
|
3780
|
+
const api2 = cause instanceof AtbashAPIError ? cause : null;
|
|
3781
|
+
const status = api2 ? ` status=${api2.status || "no-response"}` : "";
|
|
3782
|
+
const body = this.debug && api2?.body ? ` body=${truncate(api2.body, 500)}` : "";
|
|
3783
|
+
this.logger.warn?.(
|
|
3784
|
+
`[atbash] judge API failed \u2014${status} reason=${truncate(reason, 300)}${body}`,
|
|
3785
|
+
{
|
|
3786
|
+
reason,
|
|
3787
|
+
...api2 ? { status: api2.status, body: api2.body } : {},
|
|
3788
|
+
endpoint: this.endpoint,
|
|
3789
|
+
...toolCallId ? { toolCallId } : {}
|
|
3790
|
+
}
|
|
3791
|
+
);
|
|
3792
|
+
return this.fail(reason, toolCallId);
|
|
3793
|
+
}
|
|
3654
3794
|
fail(reason, toolCallId) {
|
|
3655
3795
|
return { allow: !this.failClosed, verdict: "ERROR", reason, toolCallId };
|
|
3656
3796
|
}
|
|
@@ -3991,8 +4131,27 @@ var Atbash = class _Atbash {
|
|
|
3991
4131
|
this.endpoint
|
|
3992
4132
|
);
|
|
3993
4133
|
}
|
|
3994
|
-
/**
|
|
4134
|
+
/**
|
|
4135
|
+
* Wrap a transport failure (fetch threw, no response) as an AtbashAPIError.
|
|
4136
|
+
*
|
|
4137
|
+
* `HttpTransportError.kind` names the cause; the message is already
|
|
4138
|
+
* human-readable. `debug` echoes the original exception so operators can
|
|
4139
|
+
* cross-reference with node / undici logs when a class doesn't match.
|
|
4140
|
+
*/
|
|
3995
4141
|
transportError(err) {
|
|
4142
|
+
if (err instanceof HttpTransportError) {
|
|
4143
|
+
if (this.debug) {
|
|
4144
|
+
this.logger.warn?.(
|
|
4145
|
+
`[atbash] transport failed \u2014 kind=${err.kind}`,
|
|
4146
|
+
{
|
|
4147
|
+
kind: err.kind,
|
|
4148
|
+
cause: err.cause instanceof Error ? err.cause.message : String(err.cause ?? ""),
|
|
4149
|
+
endpoint: this.endpoint
|
|
4150
|
+
}
|
|
4151
|
+
);
|
|
4152
|
+
}
|
|
4153
|
+
return new AtbashAPIError(0, err.message, "", this.endpoint);
|
|
4154
|
+
}
|
|
3996
4155
|
return new AtbashAPIError(0, errorMessage(err), "", this.endpoint);
|
|
3997
4156
|
}
|
|
3998
4157
|
async json(resp) {
|
|
@@ -4124,6 +4283,10 @@ async function safeText(resp) {
|
|
|
4124
4283
|
function errorMessage(err) {
|
|
4125
4284
|
return err instanceof Error ? err.message : String(err);
|
|
4126
4285
|
}
|
|
4286
|
+
function isEncryptionStateMismatch(err) {
|
|
4287
|
+
const msg = errorMessage(err);
|
|
4288
|
+
return msg.includes("must be a valid encryption envelope") || msg.includes("must be plaintext");
|
|
4289
|
+
}
|
|
4127
4290
|
function stringifyArgs(args) {
|
|
4128
4291
|
if (args === null || args === void 0) return "";
|
|
4129
4292
|
if (typeof args === "string") return args;
|
|
@@ -4134,9 +4297,9 @@ function stringifyArgs(args) {
|
|
|
4134
4297
|
}
|
|
4135
4298
|
}
|
|
4136
4299
|
var MAX_ACTION_LEN = 4e3;
|
|
4137
|
-
function truncate(text) {
|
|
4138
|
-
if (text.length <=
|
|
4139
|
-
return text.slice(0,
|
|
4300
|
+
function truncate(text, limit = MAX_ACTION_LEN) {
|
|
4301
|
+
if (text.length <= limit) return text;
|
|
4302
|
+
return text.slice(0, limit) + "\u2026";
|
|
4140
4303
|
}
|
|
4141
4304
|
|
|
4142
4305
|
// src-ts/redact.ts
|
|
@@ -4179,6 +4342,17 @@ function verifyJudgeResponseSignature(bodyBytes, signatureHex, pubKeyHex) {
|
|
|
4179
4342
|
};
|
|
4180
4343
|
}
|
|
4181
4344
|
|
|
4345
|
+
// src-ts/memory/boot-sync-message.ts
|
|
4346
|
+
var BOOT_SYNC_HINT = "check the chain endpoint and orgName if the cause above does not explain it";
|
|
4347
|
+
function bootSyncFailureLine(cause) {
|
|
4348
|
+
const reason = cause instanceof Error ? cause.message : String(cause);
|
|
4349
|
+
const trimmed = reason.trim();
|
|
4350
|
+
return trimmed ? `[atbash] boot memory sync failed: ${trimmed}` : (
|
|
4351
|
+
// No cause to show: fall back to the advice rather than a bare colon.
|
|
4352
|
+
`[atbash] boot memory sync failed \u2014 ${BOOT_SYNC_HINT}`
|
|
4353
|
+
);
|
|
4354
|
+
}
|
|
4355
|
+
|
|
4182
4356
|
// src-ts/memory/crypto.ts
|
|
4183
4357
|
async function deriveMemoryKey(privkey) {
|
|
4184
4358
|
return native.deriveMemoryKey(privkey);
|
|
@@ -4204,6 +4378,19 @@ async function scanMemory(entry, auth, opts) {
|
|
|
4204
4378
|
toolArgsJson: opts?.toolArgsJson ?? JSON.stringify({ key: entry.key, source: entry.source }),
|
|
4205
4379
|
mode: "memory-scan"
|
|
4206
4380
|
});
|
|
4381
|
+
const knownAction = result.actionType === "allow" || result.actionType === "block" || result.actionType === "hold_for_user_confirm";
|
|
4382
|
+
const missingVerdict = result.verdict === "No verdict" && result.status !== "logged";
|
|
4383
|
+
const unknownAction = result.actionType !== "" && !knownAction;
|
|
4384
|
+
if (missingVerdict || unknownAction) {
|
|
4385
|
+
return {
|
|
4386
|
+
safe: false,
|
|
4387
|
+
verdict: "red",
|
|
4388
|
+
reason: unknownAction ? `judge returned unrecognised action_type "${result.actionType}"` : "judge returned no verdict",
|
|
4389
|
+
confidence: result.confidence,
|
|
4390
|
+
score: native.defaultScoreForVerdict("red"),
|
|
4391
|
+
toolCallId: result.toolCallId
|
|
4392
|
+
};
|
|
4393
|
+
}
|
|
4207
4394
|
const verdict = native.mapVerdict(
|
|
4208
4395
|
result.actionType,
|
|
4209
4396
|
result.confidence,
|
|
@@ -42354,6 +42541,10 @@ var index = /* @__PURE__ */ getDefaultExportFromCjs(builtExports);
|
|
|
42354
42541
|
|
|
42355
42542
|
// src-ts/memory/chain.ts
|
|
42356
42543
|
var { createClient, encryption: encryption2, newSignatureProvider: newSignatureProvider2, Buffer: PolyBuffer } = index;
|
|
42544
|
+
var FAILOVER_CONFIG = {
|
|
42545
|
+
strategy: "tryNextOnError",
|
|
42546
|
+
attemptsPerEndpoint: 1
|
|
42547
|
+
};
|
|
42357
42548
|
function toGtxBytes(bytes) {
|
|
42358
42549
|
return PolyBuffer.from(new Uint8Array(bytes));
|
|
42359
42550
|
}
|
|
@@ -42383,7 +42574,11 @@ function materializeChain(chainOpts) {
|
|
|
42383
42574
|
}
|
|
42384
42575
|
async function buildChainClient(chainOpts) {
|
|
42385
42576
|
const { nodeUrls, blockchainRid } = materializeChain(chainOpts);
|
|
42386
|
-
return createClient({
|
|
42577
|
+
return createClient({
|
|
42578
|
+
nodeUrlPool: [...nodeUrls],
|
|
42579
|
+
blockchainRid,
|
|
42580
|
+
failOverConfig: FAILOVER_CONFIG
|
|
42581
|
+
});
|
|
42387
42582
|
}
|
|
42388
42583
|
function buildSigner(auth) {
|
|
42389
42584
|
const privKeyBuf = Buffer.from(auth.privkey, "hex");
|
|
@@ -42821,7 +43016,10 @@ var MemoryGuardManager = class {
|
|
|
42821
43016
|
await this.pointerStore.set(this.agentPubkeyHex, result.pointer);
|
|
42822
43017
|
} catch (err) {
|
|
42823
43018
|
const msg = err instanceof Error ? err.message : String(err);
|
|
42824
|
-
this.logger.warn(
|
|
43019
|
+
this.logger.warn(bootSyncFailureLine(err), {
|
|
43020
|
+
error: msg,
|
|
43021
|
+
hint: BOOT_SYNC_HINT
|
|
43022
|
+
});
|
|
42825
43023
|
}
|
|
42826
43024
|
}
|
|
42827
43025
|
/**
|
|
@@ -43049,6 +43247,7 @@ function diffMemorySnapshots(before, after) {
|
|
|
43049
43247
|
export {
|
|
43050
43248
|
Atbash,
|
|
43051
43249
|
AtbashAPIError,
|
|
43250
|
+
BOOT_SYNC_HINT,
|
|
43052
43251
|
DEFAULT_BLOCKCHAIN_RID,
|
|
43053
43252
|
DEFAULT_CHROMIA_NODE_URLS,
|
|
43054
43253
|
DEFAULT_ENDPOINT,
|
|
@@ -43056,11 +43255,16 @@ export {
|
|
|
43056
43255
|
DEFAULT_MEMORY_READ_TOOL_NAMES,
|
|
43057
43256
|
DEFAULT_MEMORY_WRITE_TOOL_NAMES,
|
|
43058
43257
|
EciesDomain,
|
|
43258
|
+
HttpClient,
|
|
43259
|
+
HttpTransportError,
|
|
43260
|
+
KEY_FILENAMES,
|
|
43059
43261
|
MemoryGuardManager,
|
|
43060
43262
|
MemoryIntegrityError,
|
|
43061
43263
|
PointerStore,
|
|
43062
43264
|
SignatureVerificationError,
|
|
43265
|
+
bootSyncFailureLine,
|
|
43063
43266
|
buildAllowedJudgeHosts,
|
|
43267
|
+
chooseKeyPath,
|
|
43064
43268
|
claimHashHex,
|
|
43065
43269
|
classifyMemoryRead,
|
|
43066
43270
|
classifyMemoryWrite,
|
|
@@ -43095,6 +43299,7 @@ export {
|
|
|
43095
43299
|
isEnvelope,
|
|
43096
43300
|
isValidPrivateKey,
|
|
43097
43301
|
keyFingerprintOf,
|
|
43302
|
+
keyPathCandidates,
|
|
43098
43303
|
loadAgent,
|
|
43099
43304
|
loadAgentFromFile,
|
|
43100
43305
|
loadUserConfig,
|