@atbash/sdk 0.18.0-dev.0 → 0.19.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/README.md +75 -12
- package/dist/browser.d.mts +145 -1
- package/dist/browser.mjs +108 -25
- package/dist/index.d.mts +145 -1
- package/dist/index.d.ts +145 -1
- package/dist/index.js +256 -40
- package/dist/index.mjs +253 -40
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -29,18 +29,15 @@ const result = await atbash.judgeAction(
|
|
|
29
29
|
"Outbound AML check — new recipient, over threshold",
|
|
30
30
|
);
|
|
31
31
|
|
|
32
|
-
// 3.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
case "BLOCK":
|
|
42
|
-
// Refused — agent is jailed in Enforcement tier
|
|
43
|
-
throw new Error(`Blocked: ${result.reason}`);
|
|
32
|
+
// 3. Act on the decision. `allow` is the gate; `verdict` says why.
|
|
33
|
+
if (result.allow) {
|
|
34
|
+
// Proceed with the action
|
|
35
|
+
} else if (result.verdict === "HOLD") {
|
|
36
|
+
// Held — operator must approve in the dashboard
|
|
37
|
+
console.log("Held for review:", result.toolCallId);
|
|
38
|
+
} else {
|
|
39
|
+
// Refused — agent is jailed in Enforcement tier
|
|
40
|
+
throw new Error(`Blocked: ${result.reason}`);
|
|
44
41
|
}
|
|
45
42
|
```
|
|
46
43
|
|
|
@@ -85,6 +82,8 @@ Every `judgeAction` call returns one of three verdicts:
|
|
|
85
82
|
| `HOLD` | Requires operator review | Pause — poll `getJudgmentStatus` until resolved |
|
|
86
83
|
| `BLOCK` | Violates a red line | Abort — agent is jailed in Enforcement tier |
|
|
87
84
|
|
|
85
|
+
> **Gate on `allow`, not on `verdict`.** `allow` is the canonical permission the SDK computes from every signal in the response; `verdict` is one of those signals, and reads as the reason. The two differ when an organisation does not enforce an agent's verdicts — Shadow Mode on an agent, or org-wide Monitor mode — where the action is judged and recorded on chain but deliberately not applied. Branching on `verdict` re-derives a denial the organisation chose not to make.
|
|
86
|
+
|
|
88
87
|
> **NB:** If your org has no active subscription, the judge returns `"No verdict"` — actions are logged on-chain for the audit trail but not evaluated by an AI provider. Assign a plan at [atbash.ai/risk-engine/settings](https://atbash.ai/risk-engine/settings) for active verdicts.
|
|
89
88
|
|
|
90
89
|
## API
|
|
@@ -195,3 +194,67 @@ Policy authoring, operator reviews, and agent management happen at [atbash.ai](h
|
|
|
195
194
|
## License
|
|
196
195
|
|
|
197
196
|
Licensed under the [Apache License, Version 2.0](LICENSE). See [NOTICE](NOTICE) for attribution. Versions published before this change remain available under the license they shipped with.
|
|
197
|
+
|
|
198
|
+
## Telemetry — what the SDK sends
|
|
199
|
+
|
|
200
|
+
The SDK reports how its own functions perform. It runs inside your agents and
|
|
201
|
+
the data leaves your network, so the payload is **metadata only** and the list
|
|
202
|
+
below is the whole of it.
|
|
203
|
+
|
|
204
|
+
**Sent**
|
|
205
|
+
|
|
206
|
+
| Field | Example |
|
|
207
|
+
| --- | --- |
|
|
208
|
+
| `function.name` | `judgeAction`, `memory.memory-add` |
|
|
209
|
+
| `status` / `outcome` | `success`, `error` |
|
|
210
|
+
| `duration_ms` | `142` |
|
|
211
|
+
| `error.class` | `AtbashAPIError` |
|
|
212
|
+
| `error.status` / `error.path` | `404`, `/api/v1/judge` — the route, never its query string |
|
|
213
|
+
| `sdk.version` | `0.18.0` |
|
|
214
|
+
| `chain` | the blockchain RID — public infrastructure, and it names no customer |
|
|
215
|
+
| `agent.hash` | SHA-256 of the agent's **public** key, never the key itself |
|
|
216
|
+
| `source` | `sdk`, `cli`, `plugin:openclaw` |
|
|
217
|
+
|
|
218
|
+
**Never sent.** Action text, tool arguments, policy text, organisation names,
|
|
219
|
+
memory file paths, memory contents, response bodies, and keys of any kind.
|
|
220
|
+
`error.path` is the route alone — the query string is stripped where the error
|
|
221
|
+
is built, because it carries org names, tool call ids and the agent pubkey. These are not fields
|
|
222
|
+
that get emptied before sending — there is no field for them to go in.
|
|
223
|
+
|
|
224
|
+
`agent.hash` is de-identification, not anonymisation: agent public keys are
|
|
225
|
+
readable from the chain, so anyone holding that list can match a hash back to
|
|
226
|
+
an agent. Supply your own salted hasher to `setupTelemetry({ hashAgentKey })`
|
|
227
|
+
if you need it to be uncorrelatable.
|
|
228
|
+
|
|
229
|
+
### Turning it off
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
export ATBASH_TELEMETRY_DISABLED=1
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
or create `~/.config/atbash/telemetry.json` containing `{ "enabled": false }`.
|
|
236
|
+
|
|
237
|
+
**On a Private deployment, telemetry may already be off for everyone.** The operator disables collection by leaving `HONEYCOMB_API_KEY` unset on their Atbash service; the telemetry route then accepts the request and discards the payload, so nothing is forwarded and agents never see an error or retry. That is an operator setting on the deployment, not one you control from the agent — the switches above are yours.
|
|
238
|
+
|
|
239
|
+
To keep the operational counters but drop the richer per-operation events:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
export ATBASH_TELEMETRY_EVENTS_DISABLED=1
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Sending it to your own collector
|
|
246
|
+
|
|
247
|
+
Point the SDK at any OTLP endpoint you control. Atbash is then bypassed
|
|
248
|
+
entirely and **no Atbash credential is created or transmitted** — your headers
|
|
249
|
+
are the only ones sent.
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
export ATBASH_TELEMETRY_COLLECTOR_URL=https://otel.yourcompany.example
|
|
253
|
+
export ATBASH_TELEMETRY_COLLECTOR_HEADERS='{"x-api-key":"your-key"}'
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Metrics go to `/v1/metrics` and events to `/v1/logs` beneath that URL. `https`
|
|
257
|
+
is required; a collector on `localhost` additionally needs
|
|
258
|
+
`ATBASH_TELEMETRY_ALLOW_LOOPBACK=1`, so a mistyped URL cannot silently turn
|
|
259
|
+
exporting off. A URL that is refused raises at setup rather than quietly
|
|
260
|
+
falling back to Atbash.
|
package/dist/browser.d.mts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Logger } from '@opentelemetry/api-logs';
|
|
2
|
+
|
|
1
3
|
type JudgeEndpointConfig = {
|
|
2
4
|
policy?: "default";
|
|
3
5
|
endpoint?: string;
|
|
@@ -1233,6 +1235,19 @@ interface GuardMemoryWriteResult {
|
|
|
1233
1235
|
/** Present when handled. True only after the chain transaction confirms. */
|
|
1234
1236
|
committed?: boolean;
|
|
1235
1237
|
}
|
|
1238
|
+
/**
|
|
1239
|
+
* Guard a memory write, and record what was decided.
|
|
1240
|
+
*
|
|
1241
|
+
* Wraps the decision rather than threading telemetry through its eight exits,
|
|
1242
|
+
* so a later return added inside cannot quietly stop being counted.
|
|
1243
|
+
*
|
|
1244
|
+
* Only a call this guard actually handled is recorded. A tool call that was
|
|
1245
|
+
* never a memory write is not a memory operation, and counting it would put
|
|
1246
|
+
* every unrelated edit into the number a memory migration reads.
|
|
1247
|
+
*
|
|
1248
|
+
* @param input - The tool call and the agent to judge it for.
|
|
1249
|
+
* @returns What the guard decided; unchanged by the recording.
|
|
1250
|
+
*/
|
|
1236
1251
|
declare function guardMemoryWrite(input: GuardMemoryWriteInput): Promise<GuardMemoryWriteResult>;
|
|
1237
1252
|
|
|
1238
1253
|
/**
|
|
@@ -1641,6 +1656,20 @@ interface TelemetryConfig {
|
|
|
1641
1656
|
* `{ Authorization: "Bearer <hex>" }`). Required to actually export.
|
|
1642
1657
|
*/
|
|
1643
1658
|
getAuthHeaders?: () => Record<string, string>;
|
|
1659
|
+
/**
|
|
1660
|
+
* Hashes the agent key before it is emitted on a wide event.
|
|
1661
|
+
*
|
|
1662
|
+
* Defaults to an unsalted SHA-256, which is de-identification rather than
|
|
1663
|
+
* anonymisation: agent pubkeys are public on chain and can be enumerated, so
|
|
1664
|
+
* the mapping is recoverable by anyone holding that list. Supply a salted
|
|
1665
|
+
* hasher to make it uncorrelatable, at the cost of joining across
|
|
1666
|
+
* deployments.
|
|
1667
|
+
*
|
|
1668
|
+
* Injected rather than imported so the telemetry modules need nothing from
|
|
1669
|
+
* the native addon. Left unset, the agent field is dropped from events
|
|
1670
|
+
* rather than falling back to the raw key.
|
|
1671
|
+
*/
|
|
1672
|
+
hashAgentKey?: (pubkeyHex: string) => string;
|
|
1644
1673
|
}
|
|
1645
1674
|
declare function setupTelemetry(config: TelemetryConfig): void;
|
|
1646
1675
|
/**
|
|
@@ -1663,6 +1692,121 @@ declare function flushTelemetry(): Promise<void>;
|
|
|
1663
1692
|
*/
|
|
1664
1693
|
declare function shutdownTelemetry(): Promise<void>;
|
|
1665
1694
|
|
|
1695
|
+
/**
|
|
1696
|
+
* Wide events: one row per SDK operation, alongside the counters.
|
|
1697
|
+
*
|
|
1698
|
+
* The counters in `telemetry.ts` are aggregated inside this process before
|
|
1699
|
+
* export, so Honeycomb never receives a per-operation row. That is fine for
|
|
1700
|
+
* "is it up" and useless for everything else: a question nobody attached an
|
|
1701
|
+
* attribute for in advance cannot be answered later, because the data to
|
|
1702
|
+
* answer it never existed. "Which org sees the most failures", "what preceded
|
|
1703
|
+
* a fail-closed", "is the new release slower" are all that shape.
|
|
1704
|
+
*
|
|
1705
|
+
* So each operation also emits one event carrying its whole context. The
|
|
1706
|
+
* counters stay — they are the right tool for health boards and alerts, and
|
|
1707
|
+
* they are not sampled.
|
|
1708
|
+
*
|
|
1709
|
+
* TWO RULES SHAPE THIS MODULE.
|
|
1710
|
+
*
|
|
1711
|
+
* The payload is METADATA ONLY, and the allowlist below is the whole of it:
|
|
1712
|
+
* function name, outcome, latency, error class, error status and path, SDK
|
|
1713
|
+
* version, chain, and a hash of the agent key. Action text, tool arguments, policy text, organisation
|
|
1714
|
+
* names and keys never appear — not as a field that is emptied, but as a field
|
|
1715
|
+
* that does not exist, so there is nothing to forget to strip.
|
|
1716
|
+
*
|
|
1717
|
+
* The agent key is hashed, never sent raw, and the hasher is INJECTED rather
|
|
1718
|
+
* than imported: this module needs nothing from the native addon. With no
|
|
1719
|
+
* hasher supplied the field is DROPPED rather than falling back to the raw
|
|
1720
|
+
* key, so the guarantee does not depend on wiring somebody could forget.
|
|
1721
|
+
*
|
|
1722
|
+
* NOTE on what hashing does and does not buy. Agent pubkeys are public on
|
|
1723
|
+
* chain and can be enumerated, so an UNSALTED hash is reversible by anyone who
|
|
1724
|
+
* can read the chain: it is de-identification, not anonymisation. A salted
|
|
1725
|
+
* hasher makes it uncorrelatable and costs cross-deployment joins. Which one
|
|
1726
|
+
* is wanted is the caller's decision; this module only guarantees the raw key
|
|
1727
|
+
* never leaves.
|
|
1728
|
+
*
|
|
1729
|
+
* And the richer payload has its own switch. Counters carry a function name
|
|
1730
|
+
* and a source. These events carry agent and org identity off a customer's
|
|
1731
|
+
* machine, which is a different proposition for a security product, so
|
|
1732
|
+
* `ATBASH_TELEMETRY_EVENTS_DISABLED=1` turns them off while leaving the health
|
|
1733
|
+
* counters on. Both remain subject to the existing global opt-out.
|
|
1734
|
+
*/
|
|
1735
|
+
|
|
1736
|
+
/** Attributes an event may carry. Anything not listed here cannot be emitted. */
|
|
1737
|
+
interface OperationEvent {
|
|
1738
|
+
/** SDK function, matching the counter's `function.name` so the two join. */
|
|
1739
|
+
functionName: string;
|
|
1740
|
+
durationMs: number;
|
|
1741
|
+
status: "success" | "error";
|
|
1742
|
+
/**
|
|
1743
|
+
* Hex pubkey of the agent the call was made as. Hashed before it is emitted,
|
|
1744
|
+
* and omitted entirely when no hasher is configured.
|
|
1745
|
+
*/
|
|
1746
|
+
agentPubkey?: string;
|
|
1747
|
+
/**
|
|
1748
|
+
* Blockchain RID of the chain this call concerned.
|
|
1749
|
+
*
|
|
1750
|
+
* The RID rather than a network label: it is public infrastructure, it is
|
|
1751
|
+
* unambiguous, and it identifies the deployment without naming a customer.
|
|
1752
|
+
*/
|
|
1753
|
+
chain?: string;
|
|
1754
|
+
/** Constructor name of the thrown error, e.g. `AtbashAPIError`. */
|
|
1755
|
+
errorClass?: string;
|
|
1756
|
+
/** HTTP status, or 0 when the request never completed. */
|
|
1757
|
+
errorStatus?: number;
|
|
1758
|
+
/**
|
|
1759
|
+
* Request path the status came from, e.g. `/api/v1/judge`.
|
|
1760
|
+
*
|
|
1761
|
+
* The class alone does not say what failed: several routes answer one call
|
|
1762
|
+
* and more than one can 404, so `AtbashAPIError` cannot distinguish "this
|
|
1763
|
+
* agent is not registered" from "the chain-routing lookup did not resolve".
|
|
1764
|
+
* The path settles it.
|
|
1765
|
+
*
|
|
1766
|
+
* Carries no query string — `requestPath` strips it at the point the error
|
|
1767
|
+
* is built, because a query string carries org names, tool call ids and the
|
|
1768
|
+
* agent pubkey. Structured and already sanitised, so this stays inside the
|
|
1769
|
+
* metadata rule where an error message would not.
|
|
1770
|
+
*/
|
|
1771
|
+
errorPath?: string;
|
|
1772
|
+
/**
|
|
1773
|
+
* Short categorical result, when "success" is too coarse — e.g. a memory
|
|
1774
|
+
* write that scanned clean but never reached the chain.
|
|
1775
|
+
*
|
|
1776
|
+
* Categorical by contract: a value a caller chooses from a fixed vocabulary,
|
|
1777
|
+
* never free text and never anything derived from user content.
|
|
1778
|
+
*/
|
|
1779
|
+
outcome?: string;
|
|
1780
|
+
}
|
|
1781
|
+
/** Hashes an agent key for emission. Supplied by `setupTelemetry`. */
|
|
1782
|
+
type AgentKeyHasher = (pubkeyHex: string) => string;
|
|
1783
|
+
/**
|
|
1784
|
+
* Point this module at a logger, or at nothing.
|
|
1785
|
+
*
|
|
1786
|
+
* Called by `setupTelemetry` once the shared exporter exists, so events and
|
|
1787
|
+
* counters travel the same authenticated route and share one opt-out decision.
|
|
1788
|
+
*
|
|
1789
|
+
* @param next - Logger to emit through, or null to disable.
|
|
1790
|
+
* @param opts - Version and source stamped on every event, and the hasher
|
|
1791
|
+
* applied to the agent key. Without a hasher, the agent field is dropped.
|
|
1792
|
+
*/
|
|
1793
|
+
declare function configureEvents(next: Logger | null, opts?: {
|
|
1794
|
+
version?: string;
|
|
1795
|
+
source?: string;
|
|
1796
|
+
hashAgentKey?: AgentKeyHasher;
|
|
1797
|
+
}): void;
|
|
1798
|
+
/** True when an event would actually be emitted. Exported for tests and callers that build context lazily. */
|
|
1799
|
+
declare function eventsAreOn(): boolean;
|
|
1800
|
+
/**
|
|
1801
|
+
* Emit one wide event for a completed operation.
|
|
1802
|
+
*
|
|
1803
|
+
* Never throws and never blocks: telemetry failing must not change what the
|
|
1804
|
+
* caller observes. Does nothing when events are off.
|
|
1805
|
+
*
|
|
1806
|
+
* @param e - The completed operation.
|
|
1807
|
+
*/
|
|
1808
|
+
declare function recordEvent(e: OperationEvent): void;
|
|
1809
|
+
|
|
1666
1810
|
/**
|
|
1667
1811
|
* Rust core does the work; `browser/encrypted-toolcall.ts` mirrors it for the
|
|
1668
1812
|
* browser and must produce the same columns.
|
|
@@ -1760,4 +1904,4 @@ declare function containsSecret(text: string): boolean;
|
|
|
1760
1904
|
declare function createMemorySnapshot(entries: MemoryEntry[], takenAt: number): MemorySnapshot;
|
|
1761
1905
|
declare function diffMemorySnapshots(before: MemorySnapshot, after: MemorySnapshot): MemoryDiffResult;
|
|
1762
1906
|
|
|
1763
|
-
export { type ActionType, type AgentAuth, type AgentLookupOptions, type AgentMemoryEntry, type AgentPolicy, type AnomalySeverity, type AnomalyType, Atbash, AtbashAPIError, type AtbashLogger, type AtbashOptions, type AtbashUserConfig, BOOT_SYNC_HINT, type ChainConfig, type ChainOpts, type ClassifierToolContext, type ClassifierToolEvent, type ClassifyMemoryReadOptions, type ClassifyMemoryWriteOptions, type ClientSource, type CommitMemoryOptions, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, DEFAULT_MEMORY_PATH_PATTERNS, DEFAULT_MEMORY_READ_TOOL_NAMES, DEFAULT_MEMORY_WRITE_TOOL_NAMES, type Decision, type DecisionVerdict, EciesDomain, type EncryptedMemory, type Envelope, type FromConfigOptions, type GuardLogger, type GuardMemoryDecision, type GuardMemoryWriteInput, type GuardMemoryWriteResult, type HeldAction, type HeldActionReview, type HookDecision, HttpClient, HttpTransportError, type JudgeEndpointConfig, type JudgeOptions, type JudgeResult, type JudgmentState, type JudgmentStatus, KEY_FILENAMES, type KeyPair, type LogToolCallOptions, type LogToolCallResult, type MemoryAnomaly, type MemoryDiffResult, type MemoryEntry, MemoryGuardManager, type MemoryGuardManagerOptions, MemoryIntegrityError, type MemoryPointer, type MemoryRollbackEvent, type MemoryScanOptions, type MemoryScanResult, type MemoryScanVerdict, type MemorySnapshot, type ModifiedEntry, type Network, type OrgSubscription, PRIVATE_CHAIN, PUBLIC_CHAIN, PointerStore, type Provider, type PubkeyValue, type RedactResult, type RollbackMemoryOptions, type SecretKind, type SecretMatch, SignatureVerificationError, type Subscription, type SyncMemoryOptions, type SyncMemoryResult, type TelemetryConfig, type TierInfo, type ToolCallFull, type ToolCallInput, type ToolCallRecord, type ValidatedEndpoint, type Verdict, type WrappedLogger, bootSyncFailureLine, buildAllowedJudgeHosts, canonicalAllow, chainForNetwork, chooseKeyPath, claimHashHex, classifyMemoryRead, classifyMemoryWrite, columnAad, commitMemoryVersion, containsEvasionCharacters, containsSecret, createFileLogger, createMemoryGuardManager, createMemorySnapshot, decryptForOrg, decryptMemoryContent, defaultPluginLogPath, defaultPointerPath, deriveMemoryKey, derivePublicKey, diffMemorySnapshots, encryptForOrg, encryptMemoryContent, encryptedLength, flushTelemetry, generateKeypair, getActiveAgentMemory, getActiveMemoryId, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRecentAgentMemory, getRollbackHistory, guardMemoryWrite, isEnvelope, isValidPrivateKey, keyFingerprintOf, keyPathCandidates, loadAgent, loadAgentFromFile, loadUserConfig, normalizeActionForHash, normalizeActionType, normalizeForMatching, normalizeStatus, normalizeVerdict, packEnvelope, parseEnvelope, pubkeyToHex, recordCall, recordDuration, redactJsonStrings, redactSecrets, resolve, resolveKeyPath, rollbackMemory, saveUserConfig, scanMemory, scanMemoryBatch, setupTelemetry, shutdownTelemetry, signEncryptedToolCall, signJudgeAction, signLogToolCall, syncLocalMemory, validateJudgeEndpoint, verifyJudgeResponseSignature, verifySignature };
|
|
1907
|
+
export { type ActionType, type AgentAuth, type AgentLookupOptions, type AgentMemoryEntry, type AgentPolicy, type AnomalySeverity, type AnomalyType, Atbash, AtbashAPIError, type AtbashLogger, type AtbashOptions, type AtbashUserConfig, BOOT_SYNC_HINT, type ChainConfig, type ChainOpts, type ClassifierToolContext, type ClassifierToolEvent, type ClassifyMemoryReadOptions, type ClassifyMemoryWriteOptions, type ClientSource, type CommitMemoryOptions, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, DEFAULT_MEMORY_PATH_PATTERNS, DEFAULT_MEMORY_READ_TOOL_NAMES, DEFAULT_MEMORY_WRITE_TOOL_NAMES, type Decision, type DecisionVerdict, EciesDomain, type EncryptedMemory, type Envelope, type FromConfigOptions, type GuardLogger, type GuardMemoryDecision, type GuardMemoryWriteInput, type GuardMemoryWriteResult, type HeldAction, type HeldActionReview, type HookDecision, HttpClient, HttpTransportError, type JudgeEndpointConfig, type JudgeOptions, type JudgeResult, type JudgmentState, type JudgmentStatus, KEY_FILENAMES, type KeyPair, type LogToolCallOptions, type LogToolCallResult, type MemoryAnomaly, type MemoryDiffResult, type MemoryEntry, MemoryGuardManager, type MemoryGuardManagerOptions, MemoryIntegrityError, type MemoryPointer, type MemoryRollbackEvent, type MemoryScanOptions, type MemoryScanResult, type MemoryScanVerdict, type MemorySnapshot, type ModifiedEntry, type Network, type OperationEvent, type OrgSubscription, PRIVATE_CHAIN, PUBLIC_CHAIN, PointerStore, type Provider, type PubkeyValue, type RedactResult, type RollbackMemoryOptions, type SecretKind, type SecretMatch, SignatureVerificationError, type Subscription, type SyncMemoryOptions, type SyncMemoryResult, type TelemetryConfig, type TierInfo, type ToolCallFull, type ToolCallInput, type ToolCallRecord, type ValidatedEndpoint, type Verdict, type WrappedLogger, bootSyncFailureLine, buildAllowedJudgeHosts, canonicalAllow, chainForNetwork, chooseKeyPath, claimHashHex, classifyMemoryRead, classifyMemoryWrite, columnAad, commitMemoryVersion, configureEvents, containsEvasionCharacters, containsSecret, createFileLogger, createMemoryGuardManager, createMemorySnapshot, decryptForOrg, decryptMemoryContent, defaultPluginLogPath, defaultPointerPath, deriveMemoryKey, derivePublicKey, diffMemorySnapshots, encryptForOrg, encryptMemoryContent, encryptedLength, eventsAreOn, flushTelemetry, generateKeypair, getActiveAgentMemory, getActiveMemoryId, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRecentAgentMemory, getRollbackHistory, guardMemoryWrite, isEnvelope, isValidPrivateKey, keyFingerprintOf, keyPathCandidates, loadAgent, loadAgentFromFile, loadUserConfig, normalizeActionForHash, normalizeActionType, normalizeForMatching, normalizeStatus, normalizeVerdict, packEnvelope, parseEnvelope, pubkeyToHex, recordCall, recordDuration, recordEvent, redactJsonStrings, redactSecrets, resolve, resolveKeyPath, rollbackMemory, saveUserConfig, scanMemory, scanMemoryBatch, setupTelemetry, shutdownTelemetry, signEncryptedToolCall, signJudgeAction, signLogToolCall, syncLocalMemory, validateJudgeEndpoint, verifyJudgeResponseSignature, verifySignature };
|
package/dist/browser.mjs
CHANGED
|
@@ -40585,7 +40585,7 @@ function requireFailoverStrategies() {
|
|
|
40585
40585
|
exports.createTimeoutPromise = createTimeoutPromise;
|
|
40586
40586
|
const utils_12 = requireUtils$1();
|
|
40587
40587
|
const httpUtil_1 = httpUtil;
|
|
40588
|
-
const
|
|
40588
|
+
const logger3 = __importStar2(logger$3);
|
|
40589
40589
|
const http_utils_1 = httpUtils;
|
|
40590
40590
|
function getUnreachableDuration(statusCode, error4) {
|
|
40591
40591
|
if ((0, http_utils_1.isNetworkError)(error4)) {
|
|
@@ -40686,7 +40686,7 @@ function requireFailoverStrategies() {
|
|
|
40686
40686
|
while (true) {
|
|
40687
40687
|
if (groupedSuccessfulResponses.maxNumberOfEqualResponses() >= bftMajorityThreshold) {
|
|
40688
40688
|
if (groupedSuccessfulResponses.numberOfDistinctResponses() > 1) {
|
|
40689
|
-
|
|
40689
|
+
logger3.warning(`Got disagreeing responses, but could still reach BFT majority`);
|
|
40690
40690
|
}
|
|
40691
40691
|
return groupedSuccessfulResponses.majorityResponse();
|
|
40692
40692
|
}
|
|
@@ -40724,7 +40724,7 @@ function requireFailoverStrategies() {
|
|
|
40724
40724
|
if (!isError4 && !error4) {
|
|
40725
40725
|
return { error: error4, statusCode, rspBody, transactionTimestamp };
|
|
40726
40726
|
}
|
|
40727
|
-
|
|
40727
|
+
logger3.info(`${method} request failed on ${endpoint.url}. Attempt: ${attempt + 1} / ${config2.attemptsPerEndpoint}`);
|
|
40728
40728
|
yield (0, utils_12.sleep)(config2.attemptInterval);
|
|
40729
40729
|
}
|
|
40730
40730
|
return { error: error4, statusCode, rspBody, transactionTimestamp };
|
|
@@ -40760,7 +40760,7 @@ function requireFailoverStrategies() {
|
|
|
40760
40760
|
if (isServerError) {
|
|
40761
40761
|
const duration = getUnreachableDuration(statusCode !== null && statusCode !== void 0 ? statusCode : void 0, response.error);
|
|
40762
40762
|
nodeManager2.makeNodeUnavailable(node2.url, duration);
|
|
40763
|
-
|
|
40763
|
+
logger3.info(`request failed with server error on ${node2.url} trying next node`);
|
|
40764
40764
|
break;
|
|
40765
40765
|
}
|
|
40766
40766
|
if (isClientError) {
|
|
@@ -40768,11 +40768,11 @@ function requireFailoverStrategies() {
|
|
|
40768
40768
|
return { error: error4, statusCode, rspBody, transactionTimestamp };
|
|
40769
40769
|
}
|
|
40770
40770
|
if (!nodeManager2.useStickyNode) {
|
|
40771
|
-
|
|
40771
|
+
logger3.info(`request failed client error on ${node2.url} trying next node`);
|
|
40772
40772
|
break;
|
|
40773
40773
|
}
|
|
40774
40774
|
}
|
|
40775
|
-
|
|
40775
|
+
logger3.info(`${method} request failed on ${node2.url}. Attempt: ${attempt + 1} / ${config2.attemptsPerEndpoint}`);
|
|
40776
40776
|
if (config2.attemptInterval > 0) {
|
|
40777
40777
|
yield (0, utils_12.sleep)(config2.attemptInterval);
|
|
40778
40778
|
}
|
|
@@ -41001,7 +41001,7 @@ function requireUtils$1() {
|
|
|
41001
41001
|
exports.getBlockchainRidFromIid = getBlockchainRidFromIid;
|
|
41002
41002
|
exports.convertToPrintable = convertToPrintable;
|
|
41003
41003
|
const buffer_12 = buffer$3;
|
|
41004
|
-
const
|
|
41004
|
+
const logger3 = __importStar2(logger$3);
|
|
41005
41005
|
const errors_12 = errors;
|
|
41006
41006
|
const gtxTool = __importStar2(gtx$1);
|
|
41007
41007
|
const errors_2 = errors;
|
|
@@ -41084,7 +41084,7 @@ function requireUtils$1() {
|
|
|
41084
41084
|
function validTxRid(txRID) {
|
|
41085
41085
|
if (txRID.length != 32) {
|
|
41086
41086
|
const error4 = new errors_12.InvalidTxRidException(txRID);
|
|
41087
|
-
|
|
41087
|
+
logger3.error(error4.toString());
|
|
41088
41088
|
return false;
|
|
41089
41089
|
}
|
|
41090
41090
|
return true;
|
|
@@ -41487,7 +41487,7 @@ function requireUtils$1() {
|
|
|
41487
41487
|
function handleGetResponse(error4, statusCode, responseObject, callback) {
|
|
41488
41488
|
try {
|
|
41489
41489
|
const responseObjectPrintable = convertToPrintable(responseObject);
|
|
41490
|
-
|
|
41490
|
+
logger3.debug(`error: ${error4}, status code: ${statusCode}, response body: ${responseObjectPrintable}`);
|
|
41491
41491
|
if (error4) {
|
|
41492
41492
|
return callback(error4, null);
|
|
41493
41493
|
}
|
|
@@ -41497,16 +41497,16 @@ function requireUtils$1() {
|
|
|
41497
41497
|
return callback(null, responseObject);
|
|
41498
41498
|
} catch (error5) {
|
|
41499
41499
|
callback(error5, null);
|
|
41500
|
-
|
|
41500
|
+
logger3.error(`client.handleGetResponse(): Failed to call the callback function. ${error5}`);
|
|
41501
41501
|
}
|
|
41502
41502
|
}
|
|
41503
41503
|
function handlePostResponse(error4, statusCode, responseObject, callback) {
|
|
41504
41504
|
var _a2;
|
|
41505
41505
|
const responseObjectPrintable = convertToPrintable(responseObject);
|
|
41506
|
-
|
|
41506
|
+
logger3.debug(`error: ${error4}, status code: ${statusCode}, response body: ${responseObjectPrintable}`);
|
|
41507
41507
|
try {
|
|
41508
41508
|
if (error4) {
|
|
41509
|
-
|
|
41509
|
+
logger3.error(`In client post(). ${error4}`);
|
|
41510
41510
|
callback(error4, null);
|
|
41511
41511
|
} else if (!statusCode || !(0, http_utils_1.isSuccessfulStatusCode)(statusCode)) {
|
|
41512
41512
|
let errorMessage2 = `Unexpected status code from server. Code: ${statusCode}.`;
|
|
@@ -41514,14 +41514,14 @@ function requireUtils$1() {
|
|
|
41514
41514
|
if (responseObjectPrintable) {
|
|
41515
41515
|
errorMessage2 += ` Message: ${responseObjectPrintable}.`;
|
|
41516
41516
|
}
|
|
41517
|
-
|
|
41517
|
+
logger3.error(errorMessage2);
|
|
41518
41518
|
callback(new errors_12.UnexpectedStatusError(statusCode !== null && statusCode !== void 0 ? statusCode : 400, errorMessageInResponseBody || responseObjectPrintable), responseObject);
|
|
41519
41519
|
} else {
|
|
41520
|
-
|
|
41520
|
+
logger3.info(`Calling responseCallback with responseObject: ${responseObjectPrintable}`);
|
|
41521
41521
|
callback(null, responseObject);
|
|
41522
41522
|
}
|
|
41523
41523
|
} catch (error5) {
|
|
41524
|
-
|
|
41524
|
+
logger3.error(`client.handlePostResponse(): Failed to call callback function ${error5}`);
|
|
41525
41525
|
}
|
|
41526
41526
|
}
|
|
41527
41527
|
function getBlockchainRidFromIid(_a2) {
|
|
@@ -42259,7 +42259,7 @@ function requireBlockchainClient() {
|
|
|
42259
42259
|
const crypto_12 = requireCryptoBrowserify();
|
|
42260
42260
|
const cloneDeep_1$1 = __importDefault2(cloneDeep_1);
|
|
42261
42261
|
const IccfProofTxMaterialBuilder_1 = requireIccfProofTxMaterialBuilder();
|
|
42262
|
-
const
|
|
42262
|
+
const logger3 = __importStar2(logger$3);
|
|
42263
42263
|
const formatter_12 = formatter;
|
|
42264
42264
|
const serialization_12 = serialization$2;
|
|
42265
42265
|
const gtxTool = __importStar2(gtx$1);
|
|
@@ -42301,7 +42301,7 @@ function requireBlockchainClient() {
|
|
|
42301
42301
|
},
|
|
42302
42302
|
signTransaction(transaction, signMethod2, callback) {
|
|
42303
42303
|
return __awaiter2(this, void 0, void 0, function* () {
|
|
42304
|
-
|
|
42304
|
+
logger3.debug(`Signing transaction with ${!(0, utils_12.isKeyPair)(signMethod2) ? "signature provider containing " : ""}pubKey: ${(0, formatter_12.toString)(signMethod2.pubKey)}`);
|
|
42305
42305
|
const gtx2 = (0, utils_12.getGTXFromBufferOrTransactionOrOperation)(transaction, config2.blockchainRid);
|
|
42306
42306
|
try {
|
|
42307
42307
|
const signedTx = yield (0, utils_12.isKeyPair)(signMethod2) ? gtxTool.sign(gtx2, signMethod2.privKey, config2.merkleHashVersion, signMethod2.pubKey) : gtxTool.sign(gtx2, signMethod2, config2.merkleHashVersion);
|
|
@@ -42326,7 +42326,7 @@ function requireBlockchainClient() {
|
|
|
42326
42326
|
const promiEvent = new promiEvents_12.Web3PromiEvent((resolve2, reject) => __awaiter2(this, void 0, void 0, function* () {
|
|
42327
42327
|
let error4 = null;
|
|
42328
42328
|
for (let i = 0; i < config2.retryTransactionPolling.count; i++) {
|
|
42329
|
-
|
|
42329
|
+
logger3.info(`sendTransactionWithRetries attempt ${i + 1} of ${config2.retryTransactionPolling.count}`);
|
|
42330
42330
|
const tmpPromiEvent = sendOnce().on(enums_12.TransactionEvent.ClusterAnchoringConfirmation, (receipt) => {
|
|
42331
42331
|
promiEvent.emit(enums_12.TransactionEvent.ClusterAnchoringConfirmation, receipt);
|
|
42332
42332
|
}).on(enums_12.TransactionEvent.SystemAnchoringConfirmation, (receipt) => {
|
|
@@ -42338,7 +42338,7 @@ function requireBlockchainClient() {
|
|
|
42338
42338
|
}).on(enums_12.TransactionEvent.DappConfirmed, (receipt) => {
|
|
42339
42339
|
promiEvent.emit(enums_12.TransactionEvent.DappConfirmed, receipt);
|
|
42340
42340
|
}).catch((tmpError) => {
|
|
42341
|
-
|
|
42341
|
+
logger3.warning(`sendTransactionWithRetries error on attempt ${i + 1} of ${config2.retryTransactionPolling.count}: ${tmpError}`);
|
|
42342
42342
|
promiEvent.emit(enums_12.TransactionEvent.Rejected, tmpError);
|
|
42343
42343
|
error4 = tmpError;
|
|
42344
42344
|
});
|
|
@@ -43073,11 +43073,11 @@ function requireDecodeTransactionToGtx() {
|
|
|
43073
43073
|
Object.defineProperty(decodeTransactionToGtx, "__esModule", { value: true });
|
|
43074
43074
|
decodeTransactionToGtx.decodeTransactionToGtx = decodeTransactionToGtx$1;
|
|
43075
43075
|
const gtxTool = __importStar2(gtx$1);
|
|
43076
|
-
const
|
|
43076
|
+
const logger3 = __importStar2(logger$3);
|
|
43077
43077
|
const dump_1 = requireDump();
|
|
43078
43078
|
function decodeTransactionToGtx$1(encodedTransaction) {
|
|
43079
43079
|
const gtx2 = gtxTool.deserialize(encodedTransaction);
|
|
43080
|
-
|
|
43080
|
+
logger3.debug(`Output from deserializing a raw transaction: ${(0, dump_1.dumpGtv)(gtx2)}`);
|
|
43081
43081
|
return gtx2;
|
|
43082
43082
|
}
|
|
43083
43083
|
return decodeTransactionToGtx;
|
|
@@ -44724,6 +44724,61 @@ function canonicalAllow(data) {
|
|
|
44724
44724
|
return verdict === "ALLOW" || verdict === "GREEN";
|
|
44725
44725
|
}
|
|
44726
44726
|
|
|
44727
|
+
// src-ts/opentel/events.ts
|
|
44728
|
+
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44729
|
+
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
44730
|
+
var SLOW_MS = 1500;
|
|
44731
|
+
var SUCCESS_SAMPLE_RATE = 10;
|
|
44732
|
+
var logger2 = null;
|
|
44733
|
+
var eventsEnabled = false;
|
|
44734
|
+
var sdkVersion = "";
|
|
44735
|
+
var eventSource = "sdk";
|
|
44736
|
+
var hashAgentKey = null;
|
|
44737
|
+
function eventsOptedOut() {
|
|
44738
|
+
const flag = process.env.ATBASH_TELEMETRY_EVENTS_DISABLED?.trim().toLowerCase();
|
|
44739
|
+
return Boolean(flag && ["1", "true", "yes", "on"].includes(flag));
|
|
44740
|
+
}
|
|
44741
|
+
function configureEvents(next, opts = {}) {
|
|
44742
|
+
logger2 = next;
|
|
44743
|
+
eventsEnabled = next !== null && !eventsOptedOut();
|
|
44744
|
+
if (opts.version) sdkVersion = opts.version;
|
|
44745
|
+
if (opts.source) eventSource = opts.source;
|
|
44746
|
+
hashAgentKey = opts.hashAgentKey ?? null;
|
|
44747
|
+
}
|
|
44748
|
+
function eventsAreOn() {
|
|
44749
|
+
return eventsEnabled && logger2 !== null;
|
|
44750
|
+
}
|
|
44751
|
+
function sampleRateFor(e) {
|
|
44752
|
+
if (e.status === "error") return 1;
|
|
44753
|
+
if (e.durationMs >= SLOW_MS) return 1;
|
|
44754
|
+
return Math.random() < 1 / SUCCESS_SAMPLE_RATE ? SUCCESS_SAMPLE_RATE : 0;
|
|
44755
|
+
}
|
|
44756
|
+
function recordEvent(e) {
|
|
44757
|
+
if (!eventsAreOn()) return;
|
|
44758
|
+
const sampleRate = sampleRateFor(e);
|
|
44759
|
+
if (sampleRate === 0) return;
|
|
44760
|
+
try {
|
|
44761
|
+
const attributes = {
|
|
44762
|
+
"function.name": e.functionName,
|
|
44763
|
+
"duration_ms": Math.round(e.durationMs),
|
|
44764
|
+
status: e.status,
|
|
44765
|
+
source: eventSource,
|
|
44766
|
+
// Honeycomb reweights counts and percentiles by this. It is per-event
|
|
44767
|
+
// because the sampling is biased by outcome and latency.
|
|
44768
|
+
sampleRate
|
|
44769
|
+
};
|
|
44770
|
+
if (sdkVersion) attributes["sdk.version"] = sdkVersion;
|
|
44771
|
+
if (e.agentPubkey && hashAgentKey) attributes["agent.hash"] = hashAgentKey(e.agentPubkey);
|
|
44772
|
+
if (e.chain) attributes["chain"] = e.chain;
|
|
44773
|
+
if (e.errorClass) attributes["error.class"] = e.errorClass;
|
|
44774
|
+
if (e.errorStatus !== void 0) attributes["error.status"] = e.errorStatus;
|
|
44775
|
+
if (e.errorPath) attributes["error.path"] = e.errorPath;
|
|
44776
|
+
if (e.outcome) attributes["outcome"] = e.outcome;
|
|
44777
|
+
logger2.emit({ body: e.functionName, attributes });
|
|
44778
|
+
} catch {
|
|
44779
|
+
}
|
|
44780
|
+
}
|
|
44781
|
+
|
|
44727
44782
|
// src-ts/browser/opentel/telemetry.ts
|
|
44728
44783
|
init_define_ATBASH_CHROMIA_NODE_URLS();
|
|
44729
44784
|
init_define_ATBASH_PRIVATE_NODE_URLS();
|
|
@@ -44791,6 +44846,13 @@ function resolveConstructorChain(options) {
|
|
|
44791
44846
|
}
|
|
44792
44847
|
return chainForNetwork(options.network ?? forcedChainNetwork() ?? "private");
|
|
44793
44848
|
}
|
|
44849
|
+
function errorDetail(err) {
|
|
44850
|
+
if (!(err instanceof AtbashAPIError)) return {};
|
|
44851
|
+
return {
|
|
44852
|
+
errorStatus: err.status,
|
|
44853
|
+
...err.path ? { errorPath: err.path } : {}
|
|
44854
|
+
};
|
|
44855
|
+
}
|
|
44794
44856
|
var Atbash = class _Atbash {
|
|
44795
44857
|
auth;
|
|
44796
44858
|
endpoint;
|
|
@@ -45001,7 +45063,7 @@ config.json still holds an "agentKey" (${identity}), but a settings file no long
|
|
|
45001
45063
|
*
|
|
45002
45064
|
* @param logger - The host logger, when one was supplied.
|
|
45003
45065
|
*/
|
|
45004
|
-
static warnOnStrandedKey(
|
|
45066
|
+
static warnOnStrandedKey(logger3) {
|
|
45005
45067
|
const stranded = strandedAgentKey();
|
|
45006
45068
|
if (!stranded) return;
|
|
45007
45069
|
let identity;
|
|
@@ -45010,7 +45072,7 @@ config.json still holds an "agentKey" (${identity}), but a settings file no long
|
|
|
45010
45072
|
} catch {
|
|
45011
45073
|
identity = "(unreadable)";
|
|
45012
45074
|
}
|
|
45013
|
-
|
|
45075
|
+
logger3?.warn?.(
|
|
45014
45076
|
`[atbash] "agentKey" in config.json is ignored \u2014 settings do not choose the signing key. It holds ${identity}; this client signs as the key file or ATBASH_AGENT_KEY instead. Move it into the key file, or delete the field, to silence this.`
|
|
45015
45077
|
);
|
|
45016
45078
|
}
|
|
@@ -45769,10 +45831,28 @@ config.json still holds an "agentKey" (${identity}), but a settings file no long
|
|
|
45769
45831
|
recordCall(name2, void 0, agentPubkey);
|
|
45770
45832
|
try {
|
|
45771
45833
|
const result = await fn();
|
|
45772
|
-
|
|
45834
|
+
const durationMs = performance.now() - start;
|
|
45835
|
+
recordDuration(name2, durationMs, "success");
|
|
45836
|
+
recordEvent({
|
|
45837
|
+
functionName: name2,
|
|
45838
|
+
durationMs,
|
|
45839
|
+
status: "success",
|
|
45840
|
+
agentPubkey,
|
|
45841
|
+
chain: this.blockchainRid
|
|
45842
|
+
});
|
|
45773
45843
|
return result;
|
|
45774
45844
|
} catch (err) {
|
|
45775
|
-
|
|
45845
|
+
const durationMs = performance.now() - start;
|
|
45846
|
+
recordDuration(name2, durationMs, "error");
|
|
45847
|
+
recordEvent({
|
|
45848
|
+
functionName: name2,
|
|
45849
|
+
durationMs,
|
|
45850
|
+
status: "error",
|
|
45851
|
+
agentPubkey,
|
|
45852
|
+
chain: this.blockchainRid,
|
|
45853
|
+
errorClass: err instanceof Error ? err.constructor.name : typeof err,
|
|
45854
|
+
...errorDetail(err)
|
|
45855
|
+
});
|
|
45776
45856
|
throw err;
|
|
45777
45857
|
}
|
|
45778
45858
|
}
|
|
@@ -46546,6 +46626,7 @@ export {
|
|
|
46546
46626
|
classifyMemoryWrite,
|
|
46547
46627
|
columnAad,
|
|
46548
46628
|
commitMemoryVersion,
|
|
46629
|
+
configureEvents,
|
|
46549
46630
|
containsEvasionCharacters2 as containsEvasionCharacters,
|
|
46550
46631
|
containsSecret2 as containsSecret,
|
|
46551
46632
|
createFileLogger,
|
|
@@ -46561,6 +46642,7 @@ export {
|
|
|
46561
46642
|
encryptForOrg,
|
|
46562
46643
|
encryptMemoryContent2 as encryptMemoryContent,
|
|
46563
46644
|
encryptedLength,
|
|
46645
|
+
eventsAreOn,
|
|
46564
46646
|
flushTelemetry,
|
|
46565
46647
|
generateKeypair2 as generateKeypair,
|
|
46566
46648
|
getActiveAgentMemory,
|
|
@@ -46589,6 +46671,7 @@ export {
|
|
|
46589
46671
|
pubkeyToHex,
|
|
46590
46672
|
recordCall,
|
|
46591
46673
|
recordDuration,
|
|
46674
|
+
recordEvent,
|
|
46592
46675
|
redactJsonStrings,
|
|
46593
46676
|
redactSecrets2 as redactSecrets,
|
|
46594
46677
|
resolve,
|