@atbash/sdk 0.3.7 → 0.3.9-dev.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/README.md +73 -23
- package/dist/index.cjs +150 -5
- package/dist/index.d.cts +18 -4
- package/dist/index.d.ts +18 -4
- package/dist/index.js +145 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,8 +21,8 @@ import { loadAgent, judgeAction } from "@atbash/sdk";
|
|
|
21
21
|
const agent = loadAgent(process.env.ATBASH_AGENT_PRIVKEY!);
|
|
22
22
|
|
|
23
23
|
// 2. Submit an action for judgment, before executing it.
|
|
24
|
-
// The SDK signs and
|
|
25
|
-
//
|
|
24
|
+
// The SDK signs the transaction locally and sends it to the judge API.
|
|
25
|
+
// Private key stays on your machine — never sent over HTTP.
|
|
26
26
|
const result = await judgeAction(
|
|
27
27
|
"Transfer $50,000 to external wallet 0xabc",
|
|
28
28
|
"Outbound AML check — new recipient, over threshold",
|
|
@@ -50,10 +50,9 @@ Before this works, the agent must be onboarded at [atbash.ai](https://atbash.ai/
|
|
|
50
50
|
|
|
51
51
|
`judgeAction()` performs a two-step flow:
|
|
52
52
|
|
|
53
|
-
1. **Sign
|
|
54
|
-
2. **Request verdict** — sends the
|
|
53
|
+
1. **Sign locally** — signs the transaction using the agent's private key. The key never leaves your machine.
|
|
54
|
+
2. **Request verdict** — sends the signed transaction, `tool_call_id`, and `agent_pubkey` to the Atbash judge API. The server broadcasts it to the Chromia blockchain and returns a verdict.
|
|
55
55
|
|
|
56
|
-
If you need finer control, you can call `logToolCall()` and the judge API separately.
|
|
57
56
|
|
|
58
57
|
### Don't have an agent yet?
|
|
59
58
|
|
|
@@ -75,12 +74,9 @@ const agent = loadAgent(privKey);
|
|
|
75
74
|
|
|
76
75
|
### Secret storage
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
-
|
|
81
|
-
- Never commit `.env` files containing the key. Add them to `.gitignore`.
|
|
82
|
-
- If a key leaks, revoke the agent and create a new one in the [Atbash dashboard](https://atbash.ai/risk-engine/agents).
|
|
83
|
-
- The SDK is **server-side only** — the key must never ship to a browser bundle.
|
|
77
|
+
- Load the private key from an environment variable (`ATBASH_AGENT_KEY`) or a secret manager — never hardcode it.
|
|
78
|
+
- Never commit `.env` files containing the key.
|
|
79
|
+
- If a key leaks, stop using it and create a new agent in the [dashboard](https://atbash.ai/risk-engine/agents).
|
|
84
80
|
|
|
85
81
|
## Verdicts
|
|
86
82
|
|
|
@@ -107,7 +103,7 @@ judgeAction(
|
|
|
107
103
|
): Promise<JudgeResult>
|
|
108
104
|
```
|
|
109
105
|
|
|
110
|
-
Submit an action for judgment before execution. Signs
|
|
106
|
+
Submit an action for judgment before execution. Signs the transaction locally and sends it to the judge API for a verdict.
|
|
111
107
|
|
|
112
108
|
```ts
|
|
113
109
|
interface AgentAuth {
|
|
@@ -154,12 +150,12 @@ logToolCall(
|
|
|
154
150
|
): Promise<LogToolCallResult>
|
|
155
151
|
```
|
|
156
152
|
|
|
157
|
-
Sign
|
|
153
|
+
Sign the transaction locally. Returns `{ success, toolCallId, signedHex?, error? }`. Use this if you need to separate the signing step from the verdict request.
|
|
158
154
|
|
|
159
155
|
### Poll judgment status
|
|
160
156
|
|
|
161
157
|
```ts
|
|
162
|
-
getJudgmentStatus(judgmentId: string, opts?: ClientOpts): Promise<JudgmentStatus>
|
|
158
|
+
getJudgmentStatus(judgmentId: string, agentPubkey: string, opts?: ClientOpts): Promise<JudgmentStatus>
|
|
163
159
|
```
|
|
164
160
|
|
|
165
161
|
Check whether a held action has been approved or rejected by an operator.
|
|
@@ -194,15 +190,15 @@ Functions that sign transactions and write to the Chromia blockchain.
|
|
|
194
190
|
|
|
195
191
|
| Function | Use case |
|
|
196
192
|
|----------|----------|
|
|
197
|
-
| `judgeAction(action, context, auth, opts?)` | Sign
|
|
198
|
-
| `logToolCall(action, context, auth, ...)` | Sign
|
|
193
|
+
| `judgeAction(action, context, auth, opts?)` | Sign locally + request a verdict from the judge API |
|
|
194
|
+
| `logToolCall(action, context, auth, ...)` | Sign the transaction locally without requesting a verdict |
|
|
199
195
|
|
|
200
196
|
### Queries
|
|
201
197
|
|
|
202
198
|
| Function | Use case |
|
|
203
199
|
|----------|----------|
|
|
204
200
|
| `checkAgentExists(pubkey, opts?)` | Check if an agent is onboarded before signing |
|
|
205
|
-
| `getJudgmentStatus(judgmentId, opts?)` | Poll whether a held action has been approved or rejected |
|
|
201
|
+
| `getJudgmentStatus(judgmentId, agentPubkey, opts?)` | Poll whether a held action has been approved or rejected |
|
|
206
202
|
| `getToolCalls(maxCount)` | List recent tool calls across all agents |
|
|
207
203
|
| `getOrgToolCalls(orgName, maxCount)` | List tool calls for a specific org |
|
|
208
204
|
| `getAgentToolCalls(pubkey, maxCount)` | List tool calls for a specific agent |
|
|
@@ -217,24 +213,78 @@ Functions that sign transactions and write to the Chromia blockchain.
|
|
|
217
213
|
|
|
218
214
|
## Configuration
|
|
219
215
|
|
|
220
|
-
|
|
216
|
+
You can pass configuration inline or use the built-in config module that reads from `~/.config/atbash/config.json`.
|
|
217
|
+
|
|
218
|
+
### Inline
|
|
221
219
|
|
|
222
220
|
```ts
|
|
223
|
-
// Custom endpoint
|
|
224
221
|
const result = await judgeAction(action, context, auth, {
|
|
225
222
|
endpoint: "https://your-instance.example.com",
|
|
223
|
+
provider: "openai",
|
|
224
|
+
model: "gpt-4o",
|
|
226
225
|
});
|
|
226
|
+
```
|
|
227
227
|
|
|
228
|
-
|
|
229
|
-
|
|
228
|
+
### Persistent config
|
|
229
|
+
|
|
230
|
+
Save configuration once — the SDK resolves values with priority: **flag > env var > config file**.
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import { saveUserConfig, resolve, loadAgent, judgeAction } from "@atbash/sdk";
|
|
234
|
+
|
|
235
|
+
// Save once
|
|
236
|
+
saveUserConfig({
|
|
237
|
+
agentKey: "9cd07a...",
|
|
238
|
+
orgName: "my_org",
|
|
230
239
|
provider: "openai",
|
|
231
|
-
model: "gpt-4o",
|
|
232
240
|
});
|
|
233
241
|
|
|
242
|
+
// Then use resolve() anywhere
|
|
243
|
+
const agent = loadAgent(resolve("agentKey"));
|
|
244
|
+
const result = await judgeAction("Transfer $500", "finance", agent, {
|
|
245
|
+
provider: resolve("provider"), // omit to use the on-chain ATBASH judge
|
|
246
|
+
});
|
|
234
247
|
```
|
|
235
248
|
|
|
249
|
+
Config file location: `~/.config/atbash/config.json`
|
|
250
|
+
|
|
251
|
+
| Function | Purpose |
|
|
252
|
+
|----------|---------|
|
|
253
|
+
| `saveUserConfig(config)` | Write config to disk |
|
|
254
|
+
| `loadUserConfig()` | Read config from disk |
|
|
255
|
+
| `resolve(key, flagValue?)` | Resolve a value: flag > env > file > `""` |
|
|
256
|
+
| `getConfigPath()` | Returns the config file path |
|
|
257
|
+
|
|
258
|
+
| Config key | Env var |
|
|
259
|
+
|------------|--------|
|
|
260
|
+
| `agentKey` | `ATBASH_AGENT_KEY` |
|
|
261
|
+
| `orgName` | `ATBASH_ORG_NAME` |
|
|
262
|
+
| `judgeEndpoint` | `ATBASH_ENDPOINT` |
|
|
263
|
+
| `blockchainRid` | `ATBASH_BLOCKCHAIN_RID` |
|
|
264
|
+
| `provider` | `ATBASH_PROVIDER` |
|
|
265
|
+
| `providerModel` | `ATBASH_PROVIDER_MODEL` |
|
|
266
|
+
|
|
236
267
|
> **Advanced:** The SDK connects to the default Atbash Chromia chain. To use a different chain, pass `chainOpts` with custom `nodeUrls` and `blockchainRid` in `JudgeOptions`.
|
|
237
268
|
|
|
269
|
+
## Secret redaction
|
|
270
|
+
|
|
271
|
+
Before each `auditToolCall` signs anything, the SDK scans `args` and `context` for secret-shaped values (API keys, tokens, JWTs, PEM blocks, etc.) and replaces matches with `[REDACTED:<kind>]`. Redaction happens **before signing**, so secrets never reach the signed bytes, the request body, the on-chain log, or the prompt sent to the AI provider.
|
|
272
|
+
|
|
273
|
+
When the redactor fires, you'll see a warning via the configured `logger`:
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
[atbash] redacted secrets before judge call { tool: "exec", count: 2, kinds: ["anthropic", "generic_token"] }
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Common `kinds`:
|
|
280
|
+
|
|
281
|
+
- `anthropic`, `openai`, `github`, `google`, `aws_access_key`, `stripe`, `slack`, `jwt`, `private_key_pem` — high-confidence vendor patterns; if you see these, a real secret was almost certainly in your input
|
|
282
|
+
- `context_secret` — a value next to a label like `api_key=`, `token:`, `password=`, etc.
|
|
283
|
+
- `generic_token` — long random-looking strings (32+ alphanumeric chars). Catches unknown-vendor secrets, but can also match UUIDs, content hashes, and other opaque identifiers. The judge sees `[REDACTED:generic_token]` instead of the original; for verdict purposes the shape of the action matters more than the exact ID, so this is generally safe — but worth knowing if you see it unexpectedly.
|
|
284
|
+
- `base64` — long base64-encoded values; can match legitimate image/file data
|
|
285
|
+
|
|
286
|
+
Redaction is silent at the consumer level — the SDK's caller still has the original arguments. Only what's sent to the judge (and persisted on chain via the verdict log) is scrubbed.
|
|
287
|
+
|
|
238
288
|
## Integration patterns
|
|
239
289
|
|
|
240
290
|
### Pre-execution gate
|
|
@@ -253,7 +303,7 @@ async function safeExecute(action: string, context: string, execute: () => Promi
|
|
|
253
303
|
```ts
|
|
254
304
|
async function waitForApproval(toolCallId: string): Promise<string> {
|
|
255
305
|
while (true) {
|
|
256
|
-
const status = await getJudgmentStatus(toolCallId);
|
|
306
|
+
const status = await getJudgmentStatus(toolCallId, auth.pubkey);
|
|
257
307
|
if (status.status === "answered") return status.verdict;
|
|
258
308
|
if (status.status === "error") throw new Error(status.reason);
|
|
259
309
|
await new Promise((r) => setTimeout(r, 5000));
|
package/dist/index.cjs
CHANGED
|
@@ -40,6 +40,8 @@ __export(index_exports, {
|
|
|
40
40
|
getAgentDetail: () => getAgentDetail,
|
|
41
41
|
getAgentPolicy: () => getAgentPolicy,
|
|
42
42
|
getAgentToolCalls: () => getAgentToolCalls,
|
|
43
|
+
getConfigDir: () => getConfigDir,
|
|
44
|
+
getConfigPath: () => getConfigPath,
|
|
43
45
|
getHeldActionReviews: () => getHeldActionReviews,
|
|
44
46
|
getJudgmentStatus: () => getJudgmentStatus,
|
|
45
47
|
getOrgTierInfo: () => getOrgTierInfo,
|
|
@@ -53,8 +55,11 @@ __export(index_exports, {
|
|
|
53
55
|
judgeAction: () => judgeAction,
|
|
54
56
|
loadAgent: () => loadAgent,
|
|
55
57
|
loadAgentFromFile: () => loadAgentFromFile,
|
|
58
|
+
loadUserConfig: () => loadUserConfig,
|
|
56
59
|
logToolCall: () => logToolCall,
|
|
60
|
+
resolve: () => resolve,
|
|
57
61
|
resolveKeyPath: () => resolveKeyPath,
|
|
62
|
+
saveUserConfig: () => saveUserConfig,
|
|
58
63
|
toPubkeyHex: () => toPubkeyHex,
|
|
59
64
|
validateJudgeEndpoint: () => validateJudgeEndpoint,
|
|
60
65
|
verifyJudgeResponseSignature: () => verifyJudgeResponseSignature
|
|
@@ -93,7 +98,7 @@ function verifyJudgeResponseSignature(bodyBytes, signatureHex, pubKeyHex) {
|
|
|
93
98
|
|
|
94
99
|
// src/client.ts
|
|
95
100
|
var { createClient, encryption: encryption2, newSignatureProvider } = import_postchain_client2.default;
|
|
96
|
-
var DEFAULT_ENDPOINT = "https://
|
|
101
|
+
var DEFAULT_ENDPOINT = "https://chromia-verified-ai-dev-two.vercel.app";
|
|
97
102
|
var DEFAULT_CHROMIA_NODE_URLS = [
|
|
98
103
|
"https://node6.testnet.chromia.com:7740",
|
|
99
104
|
"https://node7.testnet.chromia.com:7740",
|
|
@@ -333,8 +338,8 @@ async function judgeAction(action, context = "", auth, opts) {
|
|
|
333
338
|
on_chain: Boolean(data.on_chain)
|
|
334
339
|
};
|
|
335
340
|
}
|
|
336
|
-
async function getJudgmentStatus(judgmentId, opts) {
|
|
337
|
-
const url = `${baseUrl(opts)}/api/v1/judge?tool_call_id=${encodeURIComponent(judgmentId)}`;
|
|
341
|
+
async function getJudgmentStatus(judgmentId, agentPubkey, opts) {
|
|
342
|
+
const url = `${baseUrl(opts)}/api/v1/judge?tool_call_id=${encodeURIComponent(judgmentId)}&agent_pubkey=${encodeURIComponent(agentPubkey)}`;
|
|
338
343
|
const data = await getJson(url, opts);
|
|
339
344
|
return {
|
|
340
345
|
status: normalizeStatus(data.status),
|
|
@@ -540,6 +545,77 @@ function loadAgentFromFile(keyPath) {
|
|
|
540
545
|
return loadAgent(privKey);
|
|
541
546
|
}
|
|
542
547
|
|
|
548
|
+
// src/redact-secrets.ts
|
|
549
|
+
var PATTERNS = [
|
|
550
|
+
{ kind: "anthropic", re: /\bsk-ant-[A-Za-z0-9_-]{20,}/g },
|
|
551
|
+
{ kind: "openai_project", re: /\bsk-proj-[A-Za-z0-9_-]{20,}/g },
|
|
552
|
+
{ kind: "openai", re: /\bsk-[A-Za-z0-9]{20,}/g },
|
|
553
|
+
{ kind: "github", re: /\b(?:gh[pousr]|github_pat)_[A-Za-z0-9_]{30,}/g },
|
|
554
|
+
{ kind: "google", re: /\bAIza[0-9A-Za-z_-]{35}/g },
|
|
555
|
+
{ kind: "google_oauth", re: /\bya29\.[0-9A-Za-z_-]{20,}/g },
|
|
556
|
+
{
|
|
557
|
+
kind: "aws_access_key",
|
|
558
|
+
re: /\b(?:AKIA|ASIA|AGPA|AROA|ANPA|ANVA|ASCA|AIDA|AIPA)[0-9A-Z]{16}\b/g
|
|
559
|
+
},
|
|
560
|
+
{ kind: "stripe", re: /\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g },
|
|
561
|
+
{ kind: "slack", re: /\bxox[abprseo]-[A-Za-z0-9-]{10,}/g },
|
|
562
|
+
{
|
|
563
|
+
kind: "slack_webhook",
|
|
564
|
+
re: /https:\/\/hooks\.slack\.com\/services\/T[A-Za-z0-9]+\/B[A-Za-z0-9]+\/[A-Za-z0-9]{20,}/g
|
|
565
|
+
},
|
|
566
|
+
{ kind: "sendgrid", re: /\bSG\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g },
|
|
567
|
+
{ kind: "twilio_sid", re: /\bAC[0-9a-fA-F]{32}\b/g },
|
|
568
|
+
{ kind: "mailgun", re: /\bkey-[0-9a-f]{32}\b/g },
|
|
569
|
+
{ kind: "npm_token", re: /\bnpm_[A-Za-z0-9]{36,}\b/g },
|
|
570
|
+
{ kind: "jwt", re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g },
|
|
571
|
+
{
|
|
572
|
+
kind: "private_key_pem",
|
|
573
|
+
re: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
kind: "aws_secret_key",
|
|
577
|
+
re: /(?:aws[_-]?secret|secret[_-]?access[_-]?key)["'\s:=]{1,10}[A-Za-z0-9/+=]{40}/gi
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
kind: "generic_token",
|
|
581
|
+
re: /\b(?=[A-Za-z0-9_-]*[0-9])(?=[A-Za-z0-9_-]*[A-Za-z])(?![0-9a-fA-F]+$)[A-Za-z0-9_-]{32,}\b/g
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
kind: "base64",
|
|
585
|
+
re: /(?<![A-Za-z0-9+/])(?=[A-Za-z0-9+/]*[+/])(?=[A-Za-z0-9+/]*[0-9])(?=[A-Za-z0-9+/]*[A-Za-z])[A-Za-z0-9+/]{40,}={0,2}(?![A-Za-z0-9+/=])/g
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
kind: "context_secret",
|
|
589
|
+
re: /(?<![A-Za-z0-9_])(?:api[_-]?key|api[_-]?secret|access[_-]?token|refresh[_-]?token|auth[_-]?token|client[_-]?secret|password|passwd|pwd|secret|token|credential|private[_-]?key)["']?\s*[:=]\s*["']?([A-Za-z0-9+/=._-]{12,})(?=["'\s,;)\]}>]|$)/gi,
|
|
590
|
+
groupOnly: true
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
kind: "bearer",
|
|
594
|
+
re: /(?<![A-Za-z0-9_])Bearer\s+([A-Za-z0-9._-]{20,})\b/gi,
|
|
595
|
+
groupOnly: true
|
|
596
|
+
}
|
|
597
|
+
];
|
|
598
|
+
function redactSecrets(input) {
|
|
599
|
+
if (!input) return { redacted: input ?? "", found: [] };
|
|
600
|
+
const found = [];
|
|
601
|
+
let working = input;
|
|
602
|
+
for (const { kind, re, groupOnly } of PATTERNS) {
|
|
603
|
+
if (groupOnly) {
|
|
604
|
+
working = working.replace(re, (full, value) => {
|
|
605
|
+
if (typeof value !== "string" || !value) return full;
|
|
606
|
+
found.push({ kind, length: value.length });
|
|
607
|
+
return full.replace(value, `[REDACTED:${kind}]`);
|
|
608
|
+
});
|
|
609
|
+
} else {
|
|
610
|
+
working = working.replace(re, (m) => {
|
|
611
|
+
found.push({ kind, length: m.length });
|
|
612
|
+
return `[REDACTED:${kind}]`;
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
return { redacted: working, found };
|
|
617
|
+
}
|
|
618
|
+
|
|
543
619
|
// src/factory.ts
|
|
544
620
|
function createAtbashClient(config = {}) {
|
|
545
621
|
const validated = validateJudgeEndpoint(config.judge);
|
|
@@ -576,9 +652,23 @@ function createAtbashClient(config = {}) {
|
|
|
576
652
|
return fail("key load failed, blocking for safety");
|
|
577
653
|
}
|
|
578
654
|
const toolName = input.toolName || "unknown";
|
|
579
|
-
const
|
|
655
|
+
const argsRedaction = redactSecrets(stringifyArgs(input.args));
|
|
656
|
+
const ctxRedaction = redactSecrets(input.context ?? toolName);
|
|
657
|
+
const argsJson = argsRedaction.redacted;
|
|
580
658
|
const actionText = truncate(argsJson);
|
|
581
|
-
const contextText =
|
|
659
|
+
const contextText = ctxRedaction.redacted;
|
|
660
|
+
const totalRedactions = argsRedaction.found.length + ctxRedaction.found.length;
|
|
661
|
+
if (totalRedactions > 0) {
|
|
662
|
+
const kinds = [.../* @__PURE__ */ new Set([
|
|
663
|
+
...argsRedaction.found.map((f) => f.kind),
|
|
664
|
+
...ctxRedaction.found.map((f) => f.kind)
|
|
665
|
+
])];
|
|
666
|
+
logger.warn?.("[atbash] redacted secrets before judge call", {
|
|
667
|
+
tool: toolName,
|
|
668
|
+
count: totalRedactions,
|
|
669
|
+
kinds
|
|
670
|
+
});
|
|
671
|
+
}
|
|
582
672
|
try {
|
|
583
673
|
logger.info?.("[atbash] judge API called", { tool: toolName });
|
|
584
674
|
const result = await judgeAction(actionText, contextText, agent, {
|
|
@@ -648,6 +738,56 @@ function truncate(text) {
|
|
|
648
738
|
if (text.length <= MAX_ACTION_LEN) return text;
|
|
649
739
|
return text.slice(0, MAX_ACTION_LEN) + "\u2026";
|
|
650
740
|
}
|
|
741
|
+
|
|
742
|
+
// src/user-config.ts
|
|
743
|
+
var import_node_fs2 = require("fs");
|
|
744
|
+
var import_node_os2 = require("os");
|
|
745
|
+
var import_node_path2 = require("path");
|
|
746
|
+
var ENV_MAP = {
|
|
747
|
+
agentKey: "ATBASH_AGENT_KEY",
|
|
748
|
+
orgName: "ATBASH_ORG_NAME",
|
|
749
|
+
judgeEndpoint: "ATBASH_ENDPOINT",
|
|
750
|
+
blockchainRid: "ATBASH_BLOCKCHAIN_RID",
|
|
751
|
+
provider: "ATBASH_PROVIDER",
|
|
752
|
+
providerModel: "ATBASH_PROVIDER_MODEL"
|
|
753
|
+
};
|
|
754
|
+
function getConfigDir() {
|
|
755
|
+
const home = process.env.HOME || (0, import_node_os2.homedir)() || "";
|
|
756
|
+
return (0, import_node_path2.join)(home, ".config", "atbash");
|
|
757
|
+
}
|
|
758
|
+
function getConfigPath() {
|
|
759
|
+
return (0, import_node_path2.join)(getConfigDir(), "config.json");
|
|
760
|
+
}
|
|
761
|
+
function loadUserConfig() {
|
|
762
|
+
try {
|
|
763
|
+
const p = getConfigPath();
|
|
764
|
+
if (!(0, import_node_fs2.existsSync)(p)) return {};
|
|
765
|
+
const raw = (0, import_node_fs2.readFileSync)(p, "utf-8").trim();
|
|
766
|
+
if (!raw) return {};
|
|
767
|
+
return JSON.parse(raw);
|
|
768
|
+
} catch (err) {
|
|
769
|
+
console.error("Failed to load config file", err);
|
|
770
|
+
return {};
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
function saveUserConfig(config) {
|
|
774
|
+
const dir = getConfigDir();
|
|
775
|
+
if (!(0, import_node_fs2.existsSync)(dir)) {
|
|
776
|
+
(0, import_node_fs2.mkdirSync)(dir, { recursive: true });
|
|
777
|
+
}
|
|
778
|
+
(0, import_node_fs2.writeFileSync)(getConfigPath(), JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
779
|
+
}
|
|
780
|
+
function resolve(key, flagValue) {
|
|
781
|
+
if (flagValue) return flagValue;
|
|
782
|
+
const envName = ENV_MAP[key];
|
|
783
|
+
if (envName) {
|
|
784
|
+
const envVal = process.env[envName];
|
|
785
|
+
if (envVal) return envVal;
|
|
786
|
+
}
|
|
787
|
+
const fileVal = loadUserConfig()[key];
|
|
788
|
+
if (fileVal != null) return String(fileVal);
|
|
789
|
+
return "";
|
|
790
|
+
}
|
|
651
791
|
// Annotate the CommonJS export names for ESM import in node:
|
|
652
792
|
0 && (module.exports = {
|
|
653
793
|
DEFAULT_BLOCKCHAIN_RID,
|
|
@@ -660,6 +800,8 @@ function truncate(text) {
|
|
|
660
800
|
getAgentDetail,
|
|
661
801
|
getAgentPolicy,
|
|
662
802
|
getAgentToolCalls,
|
|
803
|
+
getConfigDir,
|
|
804
|
+
getConfigPath,
|
|
663
805
|
getHeldActionReviews,
|
|
664
806
|
getJudgmentStatus,
|
|
665
807
|
getOrgTierInfo,
|
|
@@ -673,8 +815,11 @@ function truncate(text) {
|
|
|
673
815
|
judgeAction,
|
|
674
816
|
loadAgent,
|
|
675
817
|
loadAgentFromFile,
|
|
818
|
+
loadUserConfig,
|
|
676
819
|
logToolCall,
|
|
820
|
+
resolve,
|
|
677
821
|
resolveKeyPath,
|
|
822
|
+
saveUserConfig,
|
|
678
823
|
toPubkeyHex,
|
|
679
824
|
validateJudgeEndpoint,
|
|
680
825
|
verifyJudgeResponseSignature
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
type Verdict = "ALLOW" | "HOLD" | "BLOCK" | "No verdict";
|
|
2
|
-
type Provider = "
|
|
2
|
+
type Provider = "openai" | "google" | "microsoft" | "custom" | (string & {});
|
|
3
3
|
type Tier = "audit" | "audit_plus" | "enforcement" | (string & {});
|
|
4
4
|
type ActionType = "allow" | "hold_for_user_confirm" | "block" | (string & {});
|
|
5
5
|
type PubkeyValue = string | Buffer | {
|
|
@@ -148,7 +148,7 @@ interface AtbashClientConfig {
|
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
declare const DEFAULT_ENDPOINT = "https://
|
|
151
|
+
declare const DEFAULT_ENDPOINT = "https://chromia-verified-ai-dev-two.vercel.app";
|
|
152
152
|
declare const DEFAULT_CHROMIA_NODE_URLS: string[];
|
|
153
153
|
declare const DEFAULT_BLOCKCHAIN_RID = "25B41DF620C489349C54944496FF5C6E58CFCEFED0C51658780B67299D40E8ED";
|
|
154
154
|
declare function isValidPrivateKey(hex: string): boolean;
|
|
@@ -176,7 +176,7 @@ declare function logToolCall(action: string, context: string, auth: AgentAuth, c
|
|
|
176
176
|
toolArgsJson?: string;
|
|
177
177
|
}, clientOpts?: ClientOpts): Promise<LogToolCallResult>;
|
|
178
178
|
declare function judgeAction(action: string, context: string | undefined, auth: AgentAuth, opts?: JudgeOptions): Promise<JudgeResult>;
|
|
179
|
-
declare function getJudgmentStatus(judgmentId: string, opts?: ClientOpts): Promise<JudgmentStatus>;
|
|
179
|
+
declare function getJudgmentStatus(judgmentId: string, agentPubkey: string, opts?: ClientOpts): Promise<JudgmentStatus>;
|
|
180
180
|
declare function getToolCalls(maxCount: number, opts?: ClientOpts): Promise<ToolCallRecord[]>;
|
|
181
181
|
declare function getOrgToolCalls(orgName: string, maxCount: number, opts?: ClientOpts): Promise<ToolCallRecord[]>;
|
|
182
182
|
declare function getAgentToolCalls(agentPubkey: string, maxCount: number, opts?: ClientOpts): Promise<ToolCallRecord[]>;
|
|
@@ -204,4 +204,18 @@ declare function verifyJudgeResponseSignature(bodyBytes: Uint8Array, signatureHe
|
|
|
204
204
|
reason?: string;
|
|
205
205
|
};
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+
interface AtbashUserConfig {
|
|
208
|
+
agentKey?: string;
|
|
209
|
+
orgName?: string;
|
|
210
|
+
judgeEndpoint?: string;
|
|
211
|
+
blockchainRid?: string;
|
|
212
|
+
provider?: string;
|
|
213
|
+
providerModel?: string;
|
|
214
|
+
}
|
|
215
|
+
declare function getConfigDir(): string;
|
|
216
|
+
declare function getConfigPath(): string;
|
|
217
|
+
declare function loadUserConfig(): AtbashUserConfig;
|
|
218
|
+
declare function saveUserConfig(config: AtbashUserConfig): void;
|
|
219
|
+
declare function resolve(key: keyof AtbashUserConfig, flagValue?: string): string;
|
|
220
|
+
|
|
221
|
+
export { type ActionType, type AgentAuth, type AgentPolicy, type AtbashClient, type AtbashClientConfig, type AtbashUserConfig, type ChainOpts, type ClientOpts, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, type Decision, type DecisionVerdict, type HeldAction, type HeldActionReview, type JudgeEndpointConfig, type JudgeOptions, type JudgeResult, type JudgmentStatus, type JudgmentStatusState, type LogToolCallResult, type Provider, type PubkeyValue, type Tier, type TierInfo, type ToolCallFull, type ToolCallInput, type ToolCallRecord, type ValidatedEndpoint, type Verdict, checkAgentExists, createAtbashClient, derivePublicKey, generateKeyPair, getAgentDetail, getAgentPolicy, getAgentToolCalls, getConfigDir, getConfigPath, getHeldActionReviews, getJudgmentStatus, getOrgTierInfo, getOrgToolCalls, getPendingHeldActions, getSafetyStats, getToolCallCount, getToolCallFull, getToolCalls, isValidPrivateKey, judgeAction, loadAgent, loadAgentFromFile, loadUserConfig, logToolCall, resolve, resolveKeyPath, saveUserConfig, toPubkeyHex, validateJudgeEndpoint, verifyJudgeResponseSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
type Verdict = "ALLOW" | "HOLD" | "BLOCK" | "No verdict";
|
|
2
|
-
type Provider = "
|
|
2
|
+
type Provider = "openai" | "google" | "microsoft" | "custom" | (string & {});
|
|
3
3
|
type Tier = "audit" | "audit_plus" | "enforcement" | (string & {});
|
|
4
4
|
type ActionType = "allow" | "hold_for_user_confirm" | "block" | (string & {});
|
|
5
5
|
type PubkeyValue = string | Buffer | {
|
|
@@ -148,7 +148,7 @@ interface AtbashClientConfig {
|
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
declare const DEFAULT_ENDPOINT = "https://
|
|
151
|
+
declare const DEFAULT_ENDPOINT = "https://chromia-verified-ai-dev-two.vercel.app";
|
|
152
152
|
declare const DEFAULT_CHROMIA_NODE_URLS: string[];
|
|
153
153
|
declare const DEFAULT_BLOCKCHAIN_RID = "25B41DF620C489349C54944496FF5C6E58CFCEFED0C51658780B67299D40E8ED";
|
|
154
154
|
declare function isValidPrivateKey(hex: string): boolean;
|
|
@@ -176,7 +176,7 @@ declare function logToolCall(action: string, context: string, auth: AgentAuth, c
|
|
|
176
176
|
toolArgsJson?: string;
|
|
177
177
|
}, clientOpts?: ClientOpts): Promise<LogToolCallResult>;
|
|
178
178
|
declare function judgeAction(action: string, context: string | undefined, auth: AgentAuth, opts?: JudgeOptions): Promise<JudgeResult>;
|
|
179
|
-
declare function getJudgmentStatus(judgmentId: string, opts?: ClientOpts): Promise<JudgmentStatus>;
|
|
179
|
+
declare function getJudgmentStatus(judgmentId: string, agentPubkey: string, opts?: ClientOpts): Promise<JudgmentStatus>;
|
|
180
180
|
declare function getToolCalls(maxCount: number, opts?: ClientOpts): Promise<ToolCallRecord[]>;
|
|
181
181
|
declare function getOrgToolCalls(orgName: string, maxCount: number, opts?: ClientOpts): Promise<ToolCallRecord[]>;
|
|
182
182
|
declare function getAgentToolCalls(agentPubkey: string, maxCount: number, opts?: ClientOpts): Promise<ToolCallRecord[]>;
|
|
@@ -204,4 +204,18 @@ declare function verifyJudgeResponseSignature(bodyBytes: Uint8Array, signatureHe
|
|
|
204
204
|
reason?: string;
|
|
205
205
|
};
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+
interface AtbashUserConfig {
|
|
208
|
+
agentKey?: string;
|
|
209
|
+
orgName?: string;
|
|
210
|
+
judgeEndpoint?: string;
|
|
211
|
+
blockchainRid?: string;
|
|
212
|
+
provider?: string;
|
|
213
|
+
providerModel?: string;
|
|
214
|
+
}
|
|
215
|
+
declare function getConfigDir(): string;
|
|
216
|
+
declare function getConfigPath(): string;
|
|
217
|
+
declare function loadUserConfig(): AtbashUserConfig;
|
|
218
|
+
declare function saveUserConfig(config: AtbashUserConfig): void;
|
|
219
|
+
declare function resolve(key: keyof AtbashUserConfig, flagValue?: string): string;
|
|
220
|
+
|
|
221
|
+
export { type ActionType, type AgentAuth, type AgentPolicy, type AtbashClient, type AtbashClientConfig, type AtbashUserConfig, type ChainOpts, type ClientOpts, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, type Decision, type DecisionVerdict, type HeldAction, type HeldActionReview, type JudgeEndpointConfig, type JudgeOptions, type JudgeResult, type JudgmentStatus, type JudgmentStatusState, type LogToolCallResult, type Provider, type PubkeyValue, type Tier, type TierInfo, type ToolCallFull, type ToolCallInput, type ToolCallRecord, type ValidatedEndpoint, type Verdict, checkAgentExists, createAtbashClient, derivePublicKey, generateKeyPair, getAgentDetail, getAgentPolicy, getAgentToolCalls, getConfigDir, getConfigPath, getHeldActionReviews, getJudgmentStatus, getOrgTierInfo, getOrgToolCalls, getPendingHeldActions, getSafetyStats, getToolCallCount, getToolCallFull, getToolCalls, isValidPrivateKey, judgeAction, loadAgent, loadAgentFromFile, loadUserConfig, logToolCall, resolve, resolveKeyPath, saveUserConfig, toPubkeyHex, validateJudgeEndpoint, verifyJudgeResponseSignature };
|
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@ function verifyJudgeResponseSignature(bodyBytes, signatureHex, pubKeyHex) {
|
|
|
30
30
|
|
|
31
31
|
// src/client.ts
|
|
32
32
|
var { createClient, encryption: encryption2, newSignatureProvider } = postchain2;
|
|
33
|
-
var DEFAULT_ENDPOINT = "https://
|
|
33
|
+
var DEFAULT_ENDPOINT = "https://chromia-verified-ai-dev-two.vercel.app";
|
|
34
34
|
var DEFAULT_CHROMIA_NODE_URLS = [
|
|
35
35
|
"https://node6.testnet.chromia.com:7740",
|
|
36
36
|
"https://node7.testnet.chromia.com:7740",
|
|
@@ -270,8 +270,8 @@ async function judgeAction(action, context = "", auth, opts) {
|
|
|
270
270
|
on_chain: Boolean(data.on_chain)
|
|
271
271
|
};
|
|
272
272
|
}
|
|
273
|
-
async function getJudgmentStatus(judgmentId, opts) {
|
|
274
|
-
const url = `${baseUrl(opts)}/api/v1/judge?tool_call_id=${encodeURIComponent(judgmentId)}`;
|
|
273
|
+
async function getJudgmentStatus(judgmentId, agentPubkey, opts) {
|
|
274
|
+
const url = `${baseUrl(opts)}/api/v1/judge?tool_call_id=${encodeURIComponent(judgmentId)}&agent_pubkey=${encodeURIComponent(agentPubkey)}`;
|
|
275
275
|
const data = await getJson(url, opts);
|
|
276
276
|
return {
|
|
277
277
|
status: normalizeStatus(data.status),
|
|
@@ -477,6 +477,77 @@ function loadAgentFromFile(keyPath) {
|
|
|
477
477
|
return loadAgent(privKey);
|
|
478
478
|
}
|
|
479
479
|
|
|
480
|
+
// src/redact-secrets.ts
|
|
481
|
+
var PATTERNS = [
|
|
482
|
+
{ kind: "anthropic", re: /\bsk-ant-[A-Za-z0-9_-]{20,}/g },
|
|
483
|
+
{ kind: "openai_project", re: /\bsk-proj-[A-Za-z0-9_-]{20,}/g },
|
|
484
|
+
{ kind: "openai", re: /\bsk-[A-Za-z0-9]{20,}/g },
|
|
485
|
+
{ kind: "github", re: /\b(?:gh[pousr]|github_pat)_[A-Za-z0-9_]{30,}/g },
|
|
486
|
+
{ kind: "google", re: /\bAIza[0-9A-Za-z_-]{35}/g },
|
|
487
|
+
{ kind: "google_oauth", re: /\bya29\.[0-9A-Za-z_-]{20,}/g },
|
|
488
|
+
{
|
|
489
|
+
kind: "aws_access_key",
|
|
490
|
+
re: /\b(?:AKIA|ASIA|AGPA|AROA|ANPA|ANVA|ASCA|AIDA|AIPA)[0-9A-Z]{16}\b/g
|
|
491
|
+
},
|
|
492
|
+
{ kind: "stripe", re: /\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g },
|
|
493
|
+
{ kind: "slack", re: /\bxox[abprseo]-[A-Za-z0-9-]{10,}/g },
|
|
494
|
+
{
|
|
495
|
+
kind: "slack_webhook",
|
|
496
|
+
re: /https:\/\/hooks\.slack\.com\/services\/T[A-Za-z0-9]+\/B[A-Za-z0-9]+\/[A-Za-z0-9]{20,}/g
|
|
497
|
+
},
|
|
498
|
+
{ kind: "sendgrid", re: /\bSG\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g },
|
|
499
|
+
{ kind: "twilio_sid", re: /\bAC[0-9a-fA-F]{32}\b/g },
|
|
500
|
+
{ kind: "mailgun", re: /\bkey-[0-9a-f]{32}\b/g },
|
|
501
|
+
{ kind: "npm_token", re: /\bnpm_[A-Za-z0-9]{36,}\b/g },
|
|
502
|
+
{ kind: "jwt", re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g },
|
|
503
|
+
{
|
|
504
|
+
kind: "private_key_pem",
|
|
505
|
+
re: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
kind: "aws_secret_key",
|
|
509
|
+
re: /(?:aws[_-]?secret|secret[_-]?access[_-]?key)["'\s:=]{1,10}[A-Za-z0-9/+=]{40}/gi
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
kind: "generic_token",
|
|
513
|
+
re: /\b(?=[A-Za-z0-9_-]*[0-9])(?=[A-Za-z0-9_-]*[A-Za-z])(?![0-9a-fA-F]+$)[A-Za-z0-9_-]{32,}\b/g
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
kind: "base64",
|
|
517
|
+
re: /(?<![A-Za-z0-9+/])(?=[A-Za-z0-9+/]*[+/])(?=[A-Za-z0-9+/]*[0-9])(?=[A-Za-z0-9+/]*[A-Za-z])[A-Za-z0-9+/]{40,}={0,2}(?![A-Za-z0-9+/=])/g
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
kind: "context_secret",
|
|
521
|
+
re: /(?<![A-Za-z0-9_])(?:api[_-]?key|api[_-]?secret|access[_-]?token|refresh[_-]?token|auth[_-]?token|client[_-]?secret|password|passwd|pwd|secret|token|credential|private[_-]?key)["']?\s*[:=]\s*["']?([A-Za-z0-9+/=._-]{12,})(?=["'\s,;)\]}>]|$)/gi,
|
|
522
|
+
groupOnly: true
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
kind: "bearer",
|
|
526
|
+
re: /(?<![A-Za-z0-9_])Bearer\s+([A-Za-z0-9._-]{20,})\b/gi,
|
|
527
|
+
groupOnly: true
|
|
528
|
+
}
|
|
529
|
+
];
|
|
530
|
+
function redactSecrets(input) {
|
|
531
|
+
if (!input) return { redacted: input ?? "", found: [] };
|
|
532
|
+
const found = [];
|
|
533
|
+
let working = input;
|
|
534
|
+
for (const { kind, re, groupOnly } of PATTERNS) {
|
|
535
|
+
if (groupOnly) {
|
|
536
|
+
working = working.replace(re, (full, value) => {
|
|
537
|
+
if (typeof value !== "string" || !value) return full;
|
|
538
|
+
found.push({ kind, length: value.length });
|
|
539
|
+
return full.replace(value, `[REDACTED:${kind}]`);
|
|
540
|
+
});
|
|
541
|
+
} else {
|
|
542
|
+
working = working.replace(re, (m) => {
|
|
543
|
+
found.push({ kind, length: m.length });
|
|
544
|
+
return `[REDACTED:${kind}]`;
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return { redacted: working, found };
|
|
549
|
+
}
|
|
550
|
+
|
|
480
551
|
// src/factory.ts
|
|
481
552
|
function createAtbashClient(config = {}) {
|
|
482
553
|
const validated = validateJudgeEndpoint(config.judge);
|
|
@@ -513,9 +584,23 @@ function createAtbashClient(config = {}) {
|
|
|
513
584
|
return fail("key load failed, blocking for safety");
|
|
514
585
|
}
|
|
515
586
|
const toolName = input.toolName || "unknown";
|
|
516
|
-
const
|
|
587
|
+
const argsRedaction = redactSecrets(stringifyArgs(input.args));
|
|
588
|
+
const ctxRedaction = redactSecrets(input.context ?? toolName);
|
|
589
|
+
const argsJson = argsRedaction.redacted;
|
|
517
590
|
const actionText = truncate(argsJson);
|
|
518
|
-
const contextText =
|
|
591
|
+
const contextText = ctxRedaction.redacted;
|
|
592
|
+
const totalRedactions = argsRedaction.found.length + ctxRedaction.found.length;
|
|
593
|
+
if (totalRedactions > 0) {
|
|
594
|
+
const kinds = [.../* @__PURE__ */ new Set([
|
|
595
|
+
...argsRedaction.found.map((f) => f.kind),
|
|
596
|
+
...ctxRedaction.found.map((f) => f.kind)
|
|
597
|
+
])];
|
|
598
|
+
logger.warn?.("[atbash] redacted secrets before judge call", {
|
|
599
|
+
tool: toolName,
|
|
600
|
+
count: totalRedactions,
|
|
601
|
+
kinds
|
|
602
|
+
});
|
|
603
|
+
}
|
|
519
604
|
try {
|
|
520
605
|
logger.info?.("[atbash] judge API called", { tool: toolName });
|
|
521
606
|
const result = await judgeAction(actionText, contextText, agent, {
|
|
@@ -585,6 +670,56 @@ function truncate(text) {
|
|
|
585
670
|
if (text.length <= MAX_ACTION_LEN) return text;
|
|
586
671
|
return text.slice(0, MAX_ACTION_LEN) + "\u2026";
|
|
587
672
|
}
|
|
673
|
+
|
|
674
|
+
// src/user-config.ts
|
|
675
|
+
import { readFileSync as readFileSync2, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
676
|
+
import { homedir as homedir2 } from "os";
|
|
677
|
+
import { join as join2 } from "path";
|
|
678
|
+
var ENV_MAP = {
|
|
679
|
+
agentKey: "ATBASH_AGENT_KEY",
|
|
680
|
+
orgName: "ATBASH_ORG_NAME",
|
|
681
|
+
judgeEndpoint: "ATBASH_ENDPOINT",
|
|
682
|
+
blockchainRid: "ATBASH_BLOCKCHAIN_RID",
|
|
683
|
+
provider: "ATBASH_PROVIDER",
|
|
684
|
+
providerModel: "ATBASH_PROVIDER_MODEL"
|
|
685
|
+
};
|
|
686
|
+
function getConfigDir() {
|
|
687
|
+
const home = process.env.HOME || homedir2() || "";
|
|
688
|
+
return join2(home, ".config", "atbash");
|
|
689
|
+
}
|
|
690
|
+
function getConfigPath() {
|
|
691
|
+
return join2(getConfigDir(), "config.json");
|
|
692
|
+
}
|
|
693
|
+
function loadUserConfig() {
|
|
694
|
+
try {
|
|
695
|
+
const p = getConfigPath();
|
|
696
|
+
if (!existsSync(p)) return {};
|
|
697
|
+
const raw = readFileSync2(p, "utf-8").trim();
|
|
698
|
+
if (!raw) return {};
|
|
699
|
+
return JSON.parse(raw);
|
|
700
|
+
} catch (err) {
|
|
701
|
+
console.error("Failed to load config file", err);
|
|
702
|
+
return {};
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
function saveUserConfig(config) {
|
|
706
|
+
const dir = getConfigDir();
|
|
707
|
+
if (!existsSync(dir)) {
|
|
708
|
+
mkdirSync(dir, { recursive: true });
|
|
709
|
+
}
|
|
710
|
+
writeFileSync(getConfigPath(), JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
711
|
+
}
|
|
712
|
+
function resolve(key, flagValue) {
|
|
713
|
+
if (flagValue) return flagValue;
|
|
714
|
+
const envName = ENV_MAP[key];
|
|
715
|
+
if (envName) {
|
|
716
|
+
const envVal = process.env[envName];
|
|
717
|
+
if (envVal) return envVal;
|
|
718
|
+
}
|
|
719
|
+
const fileVal = loadUserConfig()[key];
|
|
720
|
+
if (fileVal != null) return String(fileVal);
|
|
721
|
+
return "";
|
|
722
|
+
}
|
|
588
723
|
export {
|
|
589
724
|
DEFAULT_BLOCKCHAIN_RID,
|
|
590
725
|
DEFAULT_CHROMIA_NODE_URLS,
|
|
@@ -596,6 +731,8 @@ export {
|
|
|
596
731
|
getAgentDetail,
|
|
597
732
|
getAgentPolicy,
|
|
598
733
|
getAgentToolCalls,
|
|
734
|
+
getConfigDir,
|
|
735
|
+
getConfigPath,
|
|
599
736
|
getHeldActionReviews,
|
|
600
737
|
getJudgmentStatus,
|
|
601
738
|
getOrgTierInfo,
|
|
@@ -609,8 +746,11 @@ export {
|
|
|
609
746
|
judgeAction,
|
|
610
747
|
loadAgent,
|
|
611
748
|
loadAgentFromFile,
|
|
749
|
+
loadUserConfig,
|
|
612
750
|
logToolCall,
|
|
751
|
+
resolve,
|
|
613
752
|
resolveKeyPath,
|
|
753
|
+
saveUserConfig,
|
|
614
754
|
toPubkeyHex,
|
|
615
755
|
validateJudgeEndpoint,
|
|
616
756
|
verifyJudgeResponseSignature
|