@atbash/sdk 0.16.5-dev.0 → 0.17.0-dev.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/dist/browser.d.mts +76 -13
- package/dist/browser.mjs +277 -106
- package/dist/index.d.mts +76 -13
- package/dist/index.d.ts +76 -13
- package/dist/index.js +408 -166
- package/dist/index.mjs +408 -166
- package/package.json +7 -6
package/dist/browser.mjs
CHANGED
|
@@ -44360,6 +44360,13 @@ function buildAllowedJudgeHosts() {
|
|
|
44360
44360
|
]);
|
|
44361
44361
|
}
|
|
44362
44362
|
var ALLOWED_JUDGE_HOSTS = buildAllowedJudgeHosts();
|
|
44363
|
+
function isAllowlistedJudgeHost(endpoint) {
|
|
44364
|
+
try {
|
|
44365
|
+
return ALLOWED_JUDGE_HOSTS.has(new URL(endpoint).hostname.toLowerCase());
|
|
44366
|
+
} catch {
|
|
44367
|
+
return false;
|
|
44368
|
+
}
|
|
44369
|
+
}
|
|
44363
44370
|
function validateJudgeEndpoint(judge) {
|
|
44364
44371
|
const policy = judge?.policy === "self-hosted" ? "self-hosted" : "default";
|
|
44365
44372
|
const candidate = judge?.endpoint?.trim() || DEFAULT_ENDPOINT;
|
|
@@ -44583,7 +44590,7 @@ init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
|
44583
44590
|
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44584
44591
|
function normalizeVerdict(raw2) {
|
|
44585
44592
|
if (raw2 === null || raw2 === void 0) return "No verdict";
|
|
44586
|
-
const v = String(raw2).toUpperCase();
|
|
44593
|
+
const v = String(raw2).trim().toUpperCase();
|
|
44587
44594
|
if (v === "ALLOW" || v === "GREEN") return "ALLOW";
|
|
44588
44595
|
if (v === "HOLD" || v === "YELLOW") return "HOLD";
|
|
44589
44596
|
if (v === "BLOCK" || v === "RED") return "BLOCK";
|
|
@@ -44620,17 +44627,58 @@ function allowSignalsPermit(data) {
|
|
|
44620
44627
|
}
|
|
44621
44628
|
return signals.length === 0 || signals.every((value) => value === true);
|
|
44622
44629
|
}
|
|
44630
|
+
function explicitRefusal(data) {
|
|
44631
|
+
let hold = false;
|
|
44632
|
+
for (const source of decisionSources(data)) {
|
|
44633
|
+
const verdict = verdictOf(source);
|
|
44634
|
+
if (verdict === "BLOCK" || verdict === "RED") return "BLOCK";
|
|
44635
|
+
if (verdict === "HOLD" || verdict === "YELLOW") hold = true;
|
|
44636
|
+
const actionType = actionTypeOf(source);
|
|
44637
|
+
if (actionType === "block") return "BLOCK";
|
|
44638
|
+
if (actionType === "hold_for_user_confirm") hold = true;
|
|
44639
|
+
}
|
|
44640
|
+
if (!allowSignalsPermit(data)) return "BLOCK";
|
|
44641
|
+
return hold ? "HOLD" : "";
|
|
44642
|
+
}
|
|
44643
|
+
function decisionSources(data) {
|
|
44644
|
+
return [data, isRecord(data.decision) ? data.decision : {}];
|
|
44645
|
+
}
|
|
44646
|
+
function verdictOf(source) {
|
|
44647
|
+
return typeof source.verdict === "string" ? source.verdict.trim().toUpperCase() : "";
|
|
44648
|
+
}
|
|
44649
|
+
function actionTypeRank(actionType) {
|
|
44650
|
+
if (actionType === "block") return 4;
|
|
44651
|
+
if (actionType === "hold_for_user_confirm") return 3;
|
|
44652
|
+
if (actionType === "") return 1;
|
|
44653
|
+
if (actionType === "allow") return 0;
|
|
44654
|
+
return 2;
|
|
44655
|
+
}
|
|
44656
|
+
function actionTypeOf(source) {
|
|
44657
|
+
let winner = "";
|
|
44658
|
+
for (const key3 of ["action_type", "actionType"]) {
|
|
44659
|
+
const raw2 = source[key3];
|
|
44660
|
+
if (raw2 === void 0 || raw2 === null) continue;
|
|
44661
|
+
const actionType = normalizeActionType(raw2);
|
|
44662
|
+
if (actionTypeRank(actionType) > actionTypeRank(winner)) winner = actionType;
|
|
44663
|
+
}
|
|
44664
|
+
return winner;
|
|
44665
|
+
}
|
|
44623
44666
|
function wireActionType(data) {
|
|
44624
|
-
|
|
44625
|
-
|
|
44626
|
-
|
|
44667
|
+
for (const source of decisionSources(data)) {
|
|
44668
|
+
const actionType = actionTypeOf(source);
|
|
44669
|
+
if (actionType !== "") return actionType;
|
|
44670
|
+
}
|
|
44671
|
+
return "";
|
|
44627
44672
|
}
|
|
44628
44673
|
function isAuditTier(data) {
|
|
44629
44674
|
const absentVerdict = data.verdict === null || data.verdict === void 0;
|
|
44630
44675
|
return absentVerdict && data.status === "logged";
|
|
44631
44676
|
}
|
|
44677
|
+
function isAuditTierBody(data) {
|
|
44678
|
+
return isAuditTier(data);
|
|
44679
|
+
}
|
|
44632
44680
|
function canonicalAllow(data) {
|
|
44633
|
-
if (
|
|
44681
|
+
if (explicitRefusal(data) !== "") return false;
|
|
44634
44682
|
const actionType = wireActionType(data);
|
|
44635
44683
|
if (actionType && actionType !== "allow") return false;
|
|
44636
44684
|
if (isAuditTier(data)) return true;
|
|
@@ -44713,6 +44761,10 @@ var Atbash = class _Atbash {
|
|
|
44713
44761
|
orgEncryptionPubKey;
|
|
44714
44762
|
/** When true (default), `auditToolCall` denies on any error. */
|
|
44715
44763
|
failClosed;
|
|
44764
|
+
/** When true (default), an unenforced (audit-tier) answer is refused. */
|
|
44765
|
+
requireEnforcement;
|
|
44766
|
+
/** Overall deadline for one auditToolCall decision, in ms. */
|
|
44767
|
+
decisionTimeoutMs;
|
|
44716
44768
|
/** Org key learned from the last agent-exists check, for this agent only. */
|
|
44717
44769
|
_orgKeyFromChain = null;
|
|
44718
44770
|
debug;
|
|
@@ -44786,6 +44838,8 @@ var Atbash = class _Atbash {
|
|
|
44786
44838
|
this.verifyPubKey = validated.verifyPubKey ?? void 0;
|
|
44787
44839
|
this.orgEncryptionPubKey = options.orgEncryptionPubKey;
|
|
44788
44840
|
this.failClosed = options.failClosed !== false;
|
|
44841
|
+
this.requireEnforcement = options.requireEnforcement !== false;
|
|
44842
|
+
this.decisionTimeoutMs = options.decisionTimeoutMs ?? DEFAULT_DECISION_TIMEOUT_MS;
|
|
44789
44843
|
this.debug = options.debug === true;
|
|
44790
44844
|
this.logger = options.logger ?? {};
|
|
44791
44845
|
this.http = new HttpClient(this.endpoint, options.timeoutMs ?? 12e4);
|
|
@@ -44796,16 +44850,23 @@ var Atbash = class _Atbash {
|
|
|
44796
44850
|
verifying: this.verifyPubKey ? "with response-signature pubkey configured" : "without signature verification"
|
|
44797
44851
|
});
|
|
44798
44852
|
}
|
|
44799
|
-
|
|
44800
|
-
|
|
44801
|
-
|
|
44802
|
-
|
|
44803
|
-
|
|
44804
|
-
|
|
44805
|
-
|
|
44806
|
-
|
|
44807
|
-
|
|
44808
|
-
|
|
44853
|
+
if (isAllowlistedJudgeHost(this.endpoint)) {
|
|
44854
|
+
try {
|
|
44855
|
+
setupTelemetry({
|
|
44856
|
+
enabled: true,
|
|
44857
|
+
endpoint: this.endpoint,
|
|
44858
|
+
getAuthHeaders: () => this.authHeaders()
|
|
44859
|
+
});
|
|
44860
|
+
} catch (err) {
|
|
44861
|
+
this.logger.warn?.(
|
|
44862
|
+
"[atbash] telemetry setup failed \u2014 continuing without metrics",
|
|
44863
|
+
{ error: String(err) }
|
|
44864
|
+
);
|
|
44865
|
+
}
|
|
44866
|
+
} else {
|
|
44867
|
+
this.logger.info?.(
|
|
44868
|
+
"[atbash] telemetry disabled \u2014 the agent bearer is only sent to hosts that already receive it, and this judge endpoint is not one",
|
|
44869
|
+
{ endpoint: this.endpoint }
|
|
44809
44870
|
);
|
|
44810
44871
|
}
|
|
44811
44872
|
}
|
|
@@ -44869,6 +44930,8 @@ var Atbash = class _Atbash {
|
|
|
44869
44930
|
orgName: options.orgName,
|
|
44870
44931
|
verifyPubKey: validated.verifyPubKey ?? void 0,
|
|
44871
44932
|
failClosed: options.failClosed,
|
|
44933
|
+
requireEnforcement: options.requireEnforcement,
|
|
44934
|
+
decisionTimeoutMs: options.decisionTimeoutMs,
|
|
44872
44935
|
// ATBASH_DEBUG lets an operator turn diagnostics on without editing a
|
|
44873
44936
|
// host's plugin config, which is usually the harder half.
|
|
44874
44937
|
debug: options.debug ?? /^(1|true|yes)$/i.test(resolve("debug")),
|
|
@@ -45067,34 +45130,16 @@ var Atbash = class _Atbash {
|
|
|
45067
45130
|
}
|
|
45068
45131
|
if (!resp.ok) throw await this.httpError(resp);
|
|
45069
45132
|
const bodyBytes = Buffer.from(await resp.arrayBuffer());
|
|
45070
|
-
const verifyPubKey = options.verifyPubKey
|
|
45133
|
+
const verifyPubKey = this.effectiveVerifyKey(options.verifyPubKey);
|
|
45071
45134
|
if (verifyPubKey !== void 0) {
|
|
45072
|
-
|
|
45073
|
-
if (!sig) {
|
|
45074
|
-
throw new SignatureVerificationError(
|
|
45075
|
-
"missing X-Atbash-Signature header"
|
|
45076
|
-
);
|
|
45077
|
-
}
|
|
45078
|
-
let ok;
|
|
45079
|
-
try {
|
|
45080
|
-
ok = native.verifySignature(bodyBytes, sig, verifyPubKey);
|
|
45081
|
-
} catch (err) {
|
|
45082
|
-
throw new SignatureVerificationError(
|
|
45083
|
-
`signature verification threw: ${errorMessage(err)}`
|
|
45084
|
-
);
|
|
45085
|
-
}
|
|
45086
|
-
if (!ok) {
|
|
45087
|
-
throw new SignatureVerificationError(
|
|
45088
|
-
"signature does not verify against configured verifyPubKey"
|
|
45089
|
-
);
|
|
45090
|
-
}
|
|
45135
|
+
verifyResponseSignature(bodyBytes, resp, verifyPubKey);
|
|
45091
45136
|
}
|
|
45092
45137
|
const data = parseJson(bodyBytes);
|
|
45093
45138
|
const rawScore = data.score;
|
|
45094
45139
|
const score = typeof rawScore === "number" && Number.isInteger(rawScore) && rawScore >= 1 && rawScore <= 10 ? rawScore : void 0;
|
|
45095
45140
|
return {
|
|
45096
45141
|
verdict: normalizeVerdict(data.verdict),
|
|
45097
|
-
allow:
|
|
45142
|
+
allow: this.executable(data),
|
|
45098
45143
|
actionType: normalizeActionType(data.action_type),
|
|
45099
45144
|
reason: String(data.reason ?? ""),
|
|
45100
45145
|
confidence: Number(data.confidence ?? 0),
|
|
@@ -45105,7 +45150,8 @@ var Atbash = class _Atbash {
|
|
|
45105
45150
|
enforced: Boolean(data.enforced),
|
|
45106
45151
|
enforcementMode: String(data.enforcement_mode ?? ""),
|
|
45107
45152
|
status: String(data.status ?? ""),
|
|
45108
|
-
score
|
|
45153
|
+
score,
|
|
45154
|
+
refusal: explicitRefusal(data)
|
|
45109
45155
|
};
|
|
45110
45156
|
}
|
|
45111
45157
|
/* ── audit_tool_call (redact → judge → decision) ───────────────────────── */
|
|
@@ -45138,77 +45184,125 @@ var Atbash = class _Atbash {
|
|
|
45138
45184
|
}
|
|
45139
45185
|
try {
|
|
45140
45186
|
this.logger.info?.("[atbash] judge API called", { tool: toolName });
|
|
45141
|
-
const result = await
|
|
45142
|
-
|
|
45143
|
-
|
|
45144
|
-
|
|
45145
|
-
|
|
45146
|
-
|
|
45147
|
-
|
|
45148
|
-
|
|
45149
|
-
|
|
45150
|
-
|
|
45151
|
-
|
|
45152
|
-
|
|
45153
|
-
|
|
45154
|
-
|
|
45155
|
-
}
|
|
45156
|
-
return {
|
|
45157
|
-
allow: true,
|
|
45158
|
-
verdict: "ALLOW",
|
|
45159
|
-
reason: result.reason || "audit tier \u2014 request logged on-chain, no AI enforcement",
|
|
45160
|
-
toolCallId: result.toolCallId
|
|
45161
|
-
};
|
|
45162
|
-
}
|
|
45163
|
-
const action = result.actionType;
|
|
45164
|
-
if (action === "block") {
|
|
45187
|
+
const result = await withDeadline(
|
|
45188
|
+
this.judgeAction(actionText, contextText, {
|
|
45189
|
+
toolName,
|
|
45190
|
+
toolArgsJson: argsJson,
|
|
45191
|
+
orgName: this.orgName,
|
|
45192
|
+
// Passed through unredacted — caller vouches for the contents.
|
|
45193
|
+
resolved: input.resolved
|
|
45194
|
+
}),
|
|
45195
|
+
this.decisionTimeoutMs
|
|
45196
|
+
);
|
|
45197
|
+
return this.decide(result);
|
|
45198
|
+
} catch (err) {
|
|
45199
|
+
if (err instanceof SignatureVerificationError) {
|
|
45200
|
+
this.failJudge(errorMessage(err), err);
|
|
45165
45201
|
return {
|
|
45166
45202
|
allow: false,
|
|
45167
|
-
verdict: "
|
|
45168
|
-
reason:
|
|
45169
|
-
toolCallId: result.toolCallId
|
|
45203
|
+
verdict: "ERROR",
|
|
45204
|
+
reason: `The judge's reply failed its signature check (${errorMessage(err)}), so it was not trusted.`
|
|
45170
45205
|
};
|
|
45171
45206
|
}
|
|
45172
|
-
|
|
45173
|
-
|
|
45174
|
-
|
|
45175
|
-
|
|
45176
|
-
|
|
45177
|
-
|
|
45178
|
-
|
|
45207
|
+
return this.failJudge(errorMessage(err), err);
|
|
45208
|
+
}
|
|
45209
|
+
}
|
|
45210
|
+
/**
|
|
45211
|
+
* The verify key for one call (R4, governor tier-2 review). A per-call key
|
|
45212
|
+
* may only narrow what the client accepts: on a client pinned to a judge
|
|
45213
|
+
* key it must be that same key, never a replacement; on an unpinned client
|
|
45214
|
+
* it adds the check.
|
|
45215
|
+
*/
|
|
45216
|
+
effectiveVerifyKey(perCall) {
|
|
45217
|
+
if (perCall === void 0) return this.verifyPubKey;
|
|
45218
|
+
const key3 = perCall.trim().toLowerCase();
|
|
45219
|
+
if (this.verifyPubKey !== void 0 && key3 !== this.verifyPubKey) {
|
|
45220
|
+
throw new SignatureVerificationError(
|
|
45221
|
+
"a per-call verifyPubKey cannot replace the judge key this client is pinned to"
|
|
45222
|
+
);
|
|
45223
|
+
}
|
|
45224
|
+
return key3;
|
|
45225
|
+
}
|
|
45226
|
+
/**
|
|
45227
|
+
* Collapse a judge result into a {@link Decision}. The most restrictive
|
|
45228
|
+
* signal wins (security review 2026-09-30, H1): `action_type`, `verdict`
|
|
45229
|
+
* and the canonical `allow` are each able to deny, and only a result where
|
|
45230
|
+
* all three agree may execute. A present `allow` / `decision.allow` that is
|
|
45231
|
+
* not exactly `true` is the judge declining to grant permission, so it
|
|
45232
|
+
* denies even under `failClosed: false` — that option relaxes *errors*, it
|
|
45233
|
+
* never overrides a refusal.
|
|
45234
|
+
*/
|
|
45235
|
+
decide(result) {
|
|
45236
|
+
const toolCallId = result.toolCallId;
|
|
45237
|
+
const deny = (verdict, reason) => ({
|
|
45238
|
+
allow: false,
|
|
45239
|
+
verdict,
|
|
45240
|
+
reason,
|
|
45241
|
+
toolCallId
|
|
45242
|
+
});
|
|
45243
|
+
const notGranted = "the judge response did not grant permission";
|
|
45244
|
+
const held = deny("HOLD", result.reason || "held for human confirmation");
|
|
45245
|
+
const blocked = deny("BLOCK", result.reason || notGranted);
|
|
45246
|
+
if (result.refusal === "BLOCK") return blocked;
|
|
45247
|
+
if (result.verdict === "No verdict") {
|
|
45248
|
+
if (result.actionType === "block") {
|
|
45249
|
+
return blocked;
|
|
45250
|
+
}
|
|
45251
|
+
if (result.actionType === "hold_for_user_confirm") {
|
|
45252
|
+
return held;
|
|
45253
|
+
}
|
|
45254
|
+
if (result.refusal === "HOLD") return held;
|
|
45255
|
+
if (result.status !== "logged") {
|
|
45256
|
+
return this.failJudge(
|
|
45257
|
+
`judge returned no verdict without an audit-tier marker (status: ${result.status || "absent"})`,
|
|
45258
|
+
void 0,
|
|
45259
|
+
toolCallId
|
|
45260
|
+
);
|
|
45179
45261
|
}
|
|
45180
|
-
if (
|
|
45181
|
-
|
|
45182
|
-
|
|
45183
|
-
|
|
45184
|
-
|
|
45185
|
-
reason: result.reason,
|
|
45186
|
-
toolCallId: result.toolCallId
|
|
45187
|
-
};
|
|
45188
|
-
}
|
|
45189
|
-
if (result.verdict === "BLOCK") {
|
|
45190
|
-
return {
|
|
45191
|
-
allow: false,
|
|
45192
|
-
verdict: "BLOCK",
|
|
45193
|
-
reason: result.reason,
|
|
45194
|
-
toolCallId: result.toolCallId
|
|
45195
|
-
};
|
|
45196
|
-
}
|
|
45262
|
+
if (this.requireEnforcement) {
|
|
45263
|
+
this.logger.warn?.(
|
|
45264
|
+
"[atbash] judge did not enforce this action (audit tier) and requireEnforcement is on: denied",
|
|
45265
|
+
{ toolCallId }
|
|
45266
|
+
);
|
|
45197
45267
|
return {
|
|
45198
|
-
allow:
|
|
45199
|
-
verdict: "
|
|
45200
|
-
reason:
|
|
45201
|
-
toolCallId
|
|
45268
|
+
allow: false,
|
|
45269
|
+
verdict: "ERROR",
|
|
45270
|
+
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.",
|
|
45271
|
+
toolCallId
|
|
45202
45272
|
};
|
|
45203
45273
|
}
|
|
45204
|
-
return
|
|
45205
|
-
|
|
45206
|
-
|
|
45207
|
-
|
|
45208
|
-
|
|
45209
|
-
|
|
45210
|
-
|
|
45274
|
+
if (result.allow !== true) return deny("BLOCK", notGranted);
|
|
45275
|
+
return {
|
|
45276
|
+
allow: true,
|
|
45277
|
+
verdict: "ALLOW",
|
|
45278
|
+
reason: result.reason || "audit tier \u2014 request logged on-chain, no AI enforcement",
|
|
45279
|
+
toolCallId
|
|
45280
|
+
};
|
|
45281
|
+
}
|
|
45282
|
+
const action = result.actionType;
|
|
45283
|
+
if (action === "block") {
|
|
45284
|
+
return deny("BLOCK", result.reason || "Blocked by your organisation's Atbash policy.");
|
|
45285
|
+
}
|
|
45286
|
+
if (action === "hold_for_user_confirm") {
|
|
45287
|
+
return held;
|
|
45288
|
+
}
|
|
45289
|
+
if (result.refusal === "HOLD") return held;
|
|
45290
|
+
if (action === "allow") {
|
|
45291
|
+
if (result.verdict === "HOLD") return held;
|
|
45292
|
+
if (result.verdict === "BLOCK") return blocked;
|
|
45293
|
+
if (result.allow !== true) return deny("BLOCK", notGranted);
|
|
45294
|
+
return {
|
|
45295
|
+
allow: true,
|
|
45296
|
+
verdict: "ALLOW",
|
|
45297
|
+
reason: result.reason,
|
|
45298
|
+
toolCallId
|
|
45299
|
+
};
|
|
45211
45300
|
}
|
|
45301
|
+
return this.failJudge(
|
|
45302
|
+
"unrecognized action_type from judge",
|
|
45303
|
+
void 0,
|
|
45304
|
+
toolCallId
|
|
45305
|
+
);
|
|
45212
45306
|
}
|
|
45213
45307
|
/**
|
|
45214
45308
|
* One exit for every judge failure.
|
|
@@ -45220,18 +45314,30 @@ var Atbash = class _Atbash {
|
|
|
45220
45314
|
*/
|
|
45221
45315
|
failJudge(reason, cause, toolCallId) {
|
|
45222
45316
|
const api2 = cause instanceof AtbashAPIError ? cause : null;
|
|
45317
|
+
const userReason = userFacingReason(reason, api2);
|
|
45223
45318
|
const status = api2 ? ` status=${api2.status || "no-response"}` : "";
|
|
45319
|
+
const detail = this.debug ? ` detail=${truncate(reason, 500)}` : "";
|
|
45224
45320
|
const body = this.debug && api2?.body ? ` body=${truncate(api2.body, 500)}` : "";
|
|
45225
45321
|
this.logger.warn?.(
|
|
45226
|
-
`[atbash] judge API failed \u2014${status} reason=${truncate(
|
|
45322
|
+
`[atbash] judge API failed \u2014${status} reason=${truncate(userReason, 300)}${detail}${body}`,
|
|
45227
45323
|
{
|
|
45228
|
-
reason,
|
|
45229
|
-
...api2 ? { status: api2.status
|
|
45324
|
+
reason: userReason,
|
|
45325
|
+
...api2 ? { status: api2.status } : {},
|
|
45326
|
+
...this.debug && api2 ? { body: api2.body, detail: reason } : {},
|
|
45230
45327
|
endpoint: this.endpoint,
|
|
45231
45328
|
...toolCallId ? { toolCallId } : {}
|
|
45232
45329
|
}
|
|
45233
45330
|
);
|
|
45234
|
-
return this.fail(
|
|
45331
|
+
return this.fail(userReason, toolCallId);
|
|
45332
|
+
}
|
|
45333
|
+
/**
|
|
45334
|
+
* The canonical permission for a response body under this client's
|
|
45335
|
+
* settings: {@link canonicalAllow}, minus the audit tier when
|
|
45336
|
+
* `requireEnforcement` is on. Never more permissive than `auditToolCall`.
|
|
45337
|
+
*/
|
|
45338
|
+
executable(data) {
|
|
45339
|
+
if (!canonicalAllow(data)) return false;
|
|
45340
|
+
return !(this.requireEnforcement && isAuditTierBody(data));
|
|
45235
45341
|
}
|
|
45236
45342
|
fail(reason, toolCallId) {
|
|
45237
45343
|
return { allow: !this.failClosed, verdict: "ERROR", reason, toolCallId };
|
|
@@ -45257,11 +45363,16 @@ var Atbash = class _Atbash {
|
|
|
45257
45363
|
this.authHeaders(brid)
|
|
45258
45364
|
);
|
|
45259
45365
|
await this.raiseIfError(resp);
|
|
45260
|
-
const
|
|
45366
|
+
const bytes = Buffer.from(await resp.arrayBuffer());
|
|
45367
|
+
if (this.verifyPubKey !== void 0) {
|
|
45368
|
+
verifyResponseSignature(bytes, resp, this.verifyPubKey);
|
|
45369
|
+
}
|
|
45370
|
+
const parsed = tryParseJson(bytes.toString("utf-8"));
|
|
45371
|
+
const data = isRecord2(parsed) ? parsed : {};
|
|
45261
45372
|
return {
|
|
45262
45373
|
status: normalizeStatus(data.status),
|
|
45263
45374
|
verdict: normalizeVerdict(data.verdict),
|
|
45264
|
-
allow:
|
|
45375
|
+
allow: this.executable(data),
|
|
45265
45376
|
reason: String(data.reason ?? ""),
|
|
45266
45377
|
judgmentId: String(data.judgmentId ?? judgmentId),
|
|
45267
45378
|
onChain: optBool(data.onChain),
|
|
@@ -45736,6 +45847,66 @@ var Atbash = class _Atbash {
|
|
|
45736
45847
|
return native.containsEvasionCharacters(text);
|
|
45737
45848
|
}
|
|
45738
45849
|
};
|
|
45850
|
+
function userFacingReason(reason, api2) {
|
|
45851
|
+
if (api2 && api2.status > 0) {
|
|
45852
|
+
const where = ` (HTTP ${api2.status}${api2.path ? ` from ${api2.path}` : ""})`;
|
|
45853
|
+
const b = api2.body.toLowerCase();
|
|
45854
|
+
if (b.includes("agent not registered")) {
|
|
45855
|
+
return `Agent not registered with Atbash: onboard it in the Atbash dashboard${where}.`;
|
|
45856
|
+
}
|
|
45857
|
+
if (b.includes("jailed")) {
|
|
45858
|
+
return `This agent is jailed; unjail it in the Atbash dashboard${where}.`;
|
|
45859
|
+
}
|
|
45860
|
+
if (b.includes("agent has no policy") || b.includes("no policy configured")) {
|
|
45861
|
+
return `This agent has no policy; attach one in the Atbash dashboard${where}.`;
|
|
45862
|
+
}
|
|
45863
|
+
if (b.includes("audit tier") || b.includes("verdict disabled") || b.includes("verdict not supported")) {
|
|
45864
|
+
return `The organisation's plan does not include checked decisions${where}.`;
|
|
45865
|
+
}
|
|
45866
|
+
return `The Atbash judge answered with an error${where}, so the action was not approved.`;
|
|
45867
|
+
}
|
|
45868
|
+
const text = api2 ? api2.body || reason : reason;
|
|
45869
|
+
return truncate(text.replace(/https?:\/\/[^\s)]+/g, "the judge"), 300);
|
|
45870
|
+
}
|
|
45871
|
+
var DEFAULT_DECISION_TIMEOUT_MS = 6e4;
|
|
45872
|
+
async function withDeadline(p, ms) {
|
|
45873
|
+
let timer;
|
|
45874
|
+
const deadline = new Promise((_, reject) => {
|
|
45875
|
+
timer = setTimeout(
|
|
45876
|
+
() => reject(
|
|
45877
|
+
new Error(
|
|
45878
|
+
`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.`
|
|
45879
|
+
)
|
|
45880
|
+
),
|
|
45881
|
+
ms
|
|
45882
|
+
);
|
|
45883
|
+
});
|
|
45884
|
+
p.catch(() => void 0);
|
|
45885
|
+
try {
|
|
45886
|
+
return await Promise.race([p, deadline]);
|
|
45887
|
+
} finally {
|
|
45888
|
+
clearTimeout(timer);
|
|
45889
|
+
}
|
|
45890
|
+
}
|
|
45891
|
+
function verifyResponseSignature(bodyBytes, resp, verifyPubKey) {
|
|
45892
|
+
const sig = resp.headers.get("X-Atbash-Signature");
|
|
45893
|
+
if (!sig) {
|
|
45894
|
+
throw new SignatureVerificationError("missing X-Atbash-Signature header");
|
|
45895
|
+
}
|
|
45896
|
+
let ok;
|
|
45897
|
+
try {
|
|
45898
|
+
ok = native.verifySignature(bodyBytes, sig, verifyPubKey);
|
|
45899
|
+
} catch (err) {
|
|
45900
|
+
throw new SignatureVerificationError(
|
|
45901
|
+
`signature verification threw: ${errorMessage(err)}`
|
|
45902
|
+
);
|
|
45903
|
+
}
|
|
45904
|
+
if (!ok) {
|
|
45905
|
+
throw new SignatureVerificationError(
|
|
45906
|
+
"signature does not verify against configured verifyPubKey"
|
|
45907
|
+
);
|
|
45908
|
+
}
|
|
45909
|
+
}
|
|
45739
45910
|
function baseToolCall(raw2) {
|
|
45740
45911
|
return {
|
|
45741
45912
|
toolCallId: String(raw2.tool_call_id ?? ""),
|
|
@@ -46124,7 +46295,7 @@ async function syncLocalMemory(auth, pointer, opts = {}) {
|
|
|
46124
46295
|
if (withinTtl) {
|
|
46125
46296
|
return { drifted: false, checked: false, pointer };
|
|
46126
46297
|
}
|
|
46127
|
-
const currentId = await getActiveMemoryId(auth, opts.chainOpts);
|
|
46298
|
+
const currentId = await getActiveMemoryId(auth, opts.chainOpts, opts.filePath);
|
|
46128
46299
|
const nextPointer = { activeId: currentId, checkedAt: now };
|
|
46129
46300
|
if (currentId === pointer.activeId) {
|
|
46130
46301
|
return { drifted: false, checked: true, pointer: nextPointer };
|