@belticlabs/agent-risk-sdk 0.6.0 → 0.8.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.
@@ -1,4 +1,4 @@
1
- import { u as EvaluateOutput, D as Decision$1, w as EventResult, K as EvidenceEvent, O as EvidenceSource, ay as WireEvidenceKind, a4 as PayloadByKind, as as ToolCallStartPayload, J as JsonValue, ai as SessionClosePayload, X as JsonObject, p as DeclaredIntent, a7 as PaymentSummary, a5 as PaymentMomentPayload } from './index-IfY4XCvJ.js';
1
+ import { t as EvaluateOutput, D as Decision$1, N as JsonObject, u as EventResult, y as EvidenceEvent, F as EvidenceSource, $ as PromptBase, ac as WireEvidenceKind, U as PayloadByKind, J as JsonValue, aa as ToolCallStartPayload, a4 as SessionClosePayload, o as DeclaredIntent, W as PaymentSummary, V as PaymentMomentPayload } from './index-CBUSXzgG.js';
2
2
 
3
3
  /**
4
4
  * The platform's verdict on one payment as a value the host can ask
@@ -40,6 +40,9 @@ declare class ApiClient {
40
40
  private readonly headers;
41
41
  constructor(baseUrl: string, apiKey: string, userAgent: string);
42
42
  post<T>(path: string, body: unknown): Promise<T>;
43
+ /** A read; `query` entries left undefined are not sent. */
44
+ get<T>(path: string, query?: Record<string, string | number | undefined>): Promise<T>;
45
+ private request;
43
46
  }
44
47
 
45
48
  /**
@@ -69,18 +72,21 @@ interface AgentIdentity {
69
72
  }
70
73
 
71
74
  /**
72
- * Transport (Fraud SDK RFC › Modules: "buffering, batching, chained delivery
73
- * to the Collector"). Contract as assumed in GAP-18/38: one FIFO per
74
- * chain; at most one batch in flight per chain, so order is preserved;
75
- * exponential backoff, without end, on network / 5xx / 429 — an outage is
76
- * waited out, never surfaced into the work the evidence observes (GAP-70);
77
- * a `fork` or `rejected` ack, or a 4xx, halts the chain and surfaces
78
- * `ChainRejectedError` — an SDK must not silently keep chaining onto a
79
- * head the platform never accepted. `flush` makes one attempt per chain
80
- * now and waits for it, so read-your-writes holds when the platform is up
81
- * and a caller is not held hostage when it is down.
75
+ * One instrumented call = a `*.start` event, the work, a `*.end` event
76
+ * carrying the outcome or the error (GAP-07 correlates them by `callId`).
77
+ * `openCall` is the span — `Stream.llmCall` and `Stream.toolCall` open
78
+ * one — and `recordCall` runs the work inside it. The AI middleware, the
79
+ * tool wrapper and a host's own tool loop all record the same way.
82
80
  */
83
81
 
82
+ interface CallSpan {
83
+ readonly callId: string;
84
+ /** Resolves once `*.start` is sequenced; `end` and `fail` wait for it. */
85
+ readonly opened: Promise<boolean>;
86
+ end(outcome?: JsonObject): Promise<boolean>;
87
+ fail(error: unknown, outcome?: JsonObject): Promise<boolean>;
88
+ }
89
+
84
90
  declare class ChainRejectedError extends Error {
85
91
  readonly sessionId: string;
86
92
  readonly source: string;
@@ -89,10 +95,17 @@ declare class ChainRejectedError extends Error {
89
95
  cause?: unknown;
90
96
  });
91
97
  }
98
+ /** Which chains a `flush` sends: one session's, or every chain of the process. */
99
+ interface FlushScope {
100
+ sessionId: string;
101
+ }
92
102
  declare class Transport {
93
103
  private readonly api;
94
104
  private readonly chains;
105
+ private readonly waiting;
106
+ private running;
95
107
  private buffered;
108
+ private bufferedBytes;
96
109
  private timer;
97
110
  private closed;
98
111
  constructor(api: ApiClient);
@@ -103,21 +116,41 @@ declare class Transport {
103
116
  * invalid payload) is a fault of the client and throws.
104
117
  */
105
118
  static outage(err: unknown): boolean;
106
- get size(): number;
107
- hasRoom(): boolean;
119
+ /** The bytes the platform will measure for an event with this payload (GAP-59), known before a `seq` is spent. */
120
+ static measure(payload: unknown): number;
121
+ /** Whether the platform would take an event of this size at all. */
122
+ static fits(bytes: number): boolean;
123
+ hasRoom(bytes: number): boolean;
108
124
  haltedError(sessionId: string, source: string): ChainRejectedError | null;
109
- /** Callers check `hasRoom()` first and assign `seq` only then (GAP-38). */
110
- enqueue(ev: EvidenceEvent): void;
111
- /** One attempt per chain, now — a chain waiting out its backoff included; resolves once every attempt settled. */
112
- flush(): Promise<void>;
125
+ /** Whether the platform ended the session under this chain (GAP-85). */
126
+ ended(sessionId: string, source: string): boolean;
127
+ /** Callers check `hasRoom(bytes)` first and assign `seq` only then (GAP-38). */
128
+ enqueue(ev: EvidenceEvent, bytes: number): void;
129
+ /**
130
+ * One attempt per chain, now — a chain waiting out its backoff included;
131
+ * resolves once every attempt settled. With a scope, only that session's
132
+ * chains (GAP-88).
133
+ */
134
+ flush(scope?: FlushScope): Promise<void>;
113
135
  close(): Promise<void>;
114
136
  private schedule;
115
137
  private unschedule;
116
- /** A chain waiting out its backoff is left alone unless forced: only `flush` cuts a backoff short. */
138
+ /**
139
+ * Queues the chain for a delivery slot — at the front when forced. A
140
+ * chain waiting out its backoff is left alone unless forced: only
141
+ * `flush` cuts a backoff short.
142
+ */
117
143
  private deliver;
144
+ private promote;
145
+ private pump;
146
+ /** The head of the queue that fits one batch: by count or by bytes, whichever comes first, and never empty. */
147
+ private static batchOf;
118
148
  /** Batches until the chain drains; a retryable failure schedules the next attempt and returns. */
119
149
  private attempt;
150
+ private release;
151
+ private drop;
120
152
  private halt;
153
+ private end;
121
154
  }
122
155
 
123
156
  /**
@@ -128,9 +161,15 @@ declare class Transport {
128
161
  *
129
162
  * `seq` is handed out only when the transport has room for the event
130
163
  * (GAP-38): a dropped event never leaves a hole — the next accepted event
131
- * is preceded by a `transport.gap` that counts the drops. Payloads ship
132
- * whole (GAP-33). An outage never reaches `emit`: the transport waits it
133
- * out (GAP-70); what throws here is a chain the platform rejected.
164
+ * is preceded by a `transport.gap` that counts the drops, and how many of
165
+ * them the platform would have refused as too large (GAP-87); the size is
166
+ * measured here, once, before the seq is spent. Payloads ship whole
167
+ * (GAP-33) — except the prompt of a model call, which ships as a delta
168
+ * against the last one on the chain (GAP-89; `PromptLedger`). An outage
169
+ * never reaches `emit`: the transport waits it out (GAP-70); what throws
170
+ * here is a chain the platform rejected. A session the platform closed or
171
+ * expired is over, not broken: `emit` answers `false` and the conversation
172
+ * continues in a fresh stream (GAP-85).
134
173
  */
135
174
 
136
175
  /** Who created the session — the seller half treats a bound session as buyer-born. */
@@ -138,9 +177,18 @@ type StreamBorn = 'buyer' | 'seller';
138
177
  interface StreamDeps {
139
178
  transport: Transport;
140
179
  signer?: Signer | undefined;
180
+ /** The conversation's last prompt, when resuming one: what the first model call ships a delta against (GAP-89). */
181
+ prompt?: PromptBase | undefined;
141
182
  /** Called once the stream closed, so the registry can forget it. */
142
183
  onClosed?: ((stream: Stream) => void) | undefined;
143
184
  }
185
+ /** What the host knows of a model call before it runs: the provider-level options, prompt included (GAP-57). */
186
+ interface LlmCallInput {
187
+ callId: string;
188
+ provider: string;
189
+ modelId: string;
190
+ params: Record<string, JsonValue>;
191
+ }
144
192
  /**
145
193
  * One tool call as a span: `tool_call.start` now, `tool_call.end` with the
146
194
  * outcome and the elapsed time when the host reports it.
@@ -159,25 +207,41 @@ interface ToolCallSpan {
159
207
  declare class Stream {
160
208
  private readonly deps;
161
209
  readonly id: string;
210
+ /** The conversation this session belongs to — the root's id (GAP-84). */
211
+ readonly conversationId: string;
162
212
  readonly source: EvidenceSource;
163
213
  readonly born: StreamBorn;
164
214
  private chain;
215
+ private readonly ledger;
165
216
  private building;
166
217
  private dropped;
218
+ private oversized;
167
219
  private droppedFirstTs;
168
220
  private droppedLastTs;
169
221
  private closed;
170
- constructor(deps: StreamDeps, id: string, source: EvidenceSource, born: StreamBorn);
222
+ constructor(deps: StreamDeps, id: string,
223
+ /** The conversation this session belongs to — the root's id (GAP-84). */
224
+ conversationId: string, source: EvidenceSource, born: StreamBorn);
225
+ /** Closed by this side, or ended by the platform (GAP-85). */
171
226
  get isClosed(): boolean;
172
227
  /**
173
228
  * Resolves once the event is sequenced and buffered — not once it is
174
229
  * acknowledged. `false` when the event was dropped for lack of room.
175
230
  */
176
231
  emit<K extends WireEvidenceKind>(kind: K, payload: PayloadByKind[K]): Promise<boolean>;
232
+ /** What the drops since the last accepted event add up to (GAP-38/87). */
233
+ private gap;
234
+ /**
235
+ * A model call as a span: `llm_call.start` now, with the prompt as a
236
+ * delta against the last one on this chain (GAP-89), `llm_call.end` when
237
+ * the host reports the result. A start that never left (dropped) forgets
238
+ * the ledger, so the next call ships its prompt whole.
239
+ */
240
+ llmCall(call: LlmCallInput): CallSpan;
177
241
  /** The tool call whose `execute` the host runs itself; see `ToolCallSpan`. */
178
242
  toolCall(call: ToolCallStartPayload): ToolCallSpan;
179
243
  close(reason?: SessionClosePayload['reason'], extra?: JsonObject): Promise<void>;
180
- /** Read-your-writes: the platform must hold the evidence before anyone judges it (GAP-16/66). */
244
+ /** Read-your-writes for this session's chains, and only them (GAP-16/66/88). */
181
245
  flush(): Promise<void>;
182
246
  /** Serialized: two concurrent emits get consecutive seqs, never the same one. */
183
247
  private next;
@@ -187,16 +251,18 @@ declare class Stream {
187
251
  * The registry of evidence streams, one object per (session, source) per
188
252
  * process: a chain's head lives in it, so two objects for the same chain
189
253
  * would both start at seq 0 and fork it. Closed streams are forgotten; a
190
- * process restart mid-session still loses the head (GAP-67).
254
+ * process never continues a chain it did not start — it resumes the
255
+ * conversation in a fresh one (GAP-67/84).
191
256
  *
192
- * The buyer half opens AGENT_TRACE sessions keyed by the host's own id
193
- * (GAP-71) and announces them with `session.open` (seq 0) and
257
+ * The buyer half opens AGENT_TRACE sessions, new or resuming a
258
+ * conversation, and announces them with `session.open` (seq 0) and
194
259
  * `intent.declared` (seq 1; GAP-23/60). A session the platform could not
195
- * open — an outage — resolves `null` for every key during `OPEN_RETRY_MS`,
196
- * so the host runs without evidence instead of paying a failed request on
197
- * every step (GAP-70); a refused one (4xx) throws, and the next call tries
198
- * again. The seller half attaches to a bound session or opens its own
199
- * INTERNAL_NETWORK one (GAP-13).
260
+ * open — an outage — resolves `null` for every caller during
261
+ * `OPEN_RETRY_MS`, so the host runs without evidence instead of paying a
262
+ * failed request on every step (GAP-70); a refused one (4xx) throws, and
263
+ * the next call tries again. A resumed conversation's stream starts from
264
+ * the prompt base the platform answered (GAP-89). The seller half attaches
265
+ * to a bound session or opens its own INTERNAL_NETWORK one (GAP-13).
200
266
  */
201
267
 
202
268
  interface StartInput {
@@ -207,6 +273,10 @@ interface StartInput {
207
273
  } | undefined;
208
274
  attestations?: JsonObject | undefined;
209
275
  }
276
+ interface OpenInput extends StartInput {
277
+ /** The conversation to continue: any session id of it (GAP-84). */
278
+ resume?: string | undefined;
279
+ }
210
280
  interface StreamsDeps {
211
281
  api: ApiClient;
212
282
  transport: Transport;
@@ -216,20 +286,17 @@ interface StreamsDeps {
216
286
  declare class Streams {
217
287
  private readonly deps;
218
288
  private readonly attached;
219
- /** Buyer streams by the host's own key (GAP-71). */
220
- private readonly opened;
221
289
  private retryAt;
222
290
  constructor(deps: StreamsDeps);
223
291
  /**
224
- * Buyer half: the stream for a key of the host's own, opened on first
225
- * use and reused after. A halted chain is reopened as a fresh session
226
- * that continues the same key; a closed key is forgotten.
292
+ * Buyer half: a fresh AGENT_TRACE stream — a new conversation, or a new
293
+ * session of the one `resume` names. `null` while the platform is out.
227
294
  */
228
- open(key: string, input?: StartInput): Promise<Stream | null>;
295
+ open(input?: OpenInput, onClosed?: () => void): Promise<Stream | null>;
229
296
  /** Seller half: emit INTERNAL_NETWORK evidence into a session the buyer bound, or open a seller-born one. */
230
297
  ensure(sessionId?: string | null): Promise<Stream>;
231
- private forget;
232
- private openFresh;
298
+ /** Whether the platform refused this stream's chain: its next `emit` throws (GAP-85). */
299
+ halted(stream: Stream): boolean;
233
300
  private create;
234
301
  private attach;
235
302
  }
@@ -255,16 +322,19 @@ interface DecideOptions {
255
322
  }
256
323
  interface SessionDeps {
257
324
  streams: Streams;
258
- evaluate: (sessionId: string, payment: PaymentSummary) => Promise<Decision>;
325
+ evaluate: (sessionId: string, payment: PaymentSummary, callId?: string) => Promise<Decision>;
326
+ /** Called once the platform answered with the conversation id, so the registry can key the handle by it. */
327
+ onOpened: (session: Session, conversationId: string) => void;
259
328
  /** Called once the session closed, so the registry forgets it. */
260
329
  onClosed: (session: Session) => void;
261
330
  }
262
331
  declare class Session {
263
332
  private readonly deps;
264
- readonly key: string;
265
333
  private readonly opts;
266
334
  private opened;
267
335
  private current;
336
+ /** The conversation id: what was resumed, then what the platform answered. */
337
+ private conversationId;
268
338
  /** JCS hash of the mandate on the chain, and of the one the options carried. */
269
339
  private declared;
270
340
  private readonly openedWith;
@@ -272,9 +342,14 @@ declare class Session {
272
342
  private timer;
273
343
  private readonly calls;
274
344
  private readonly decisions;
275
- constructor(deps: SessionDeps, key: string, opts?: SessionOptions);
276
- /** The platform's id for this session — opened on first use, `null` while there is none. */
345
+ constructor(deps: SessionDeps, opts?: SessionOptions, resume?: string | null);
346
+ /**
347
+ * The conversation id — what the host stores and resumes with (GAP-84).
348
+ * Opened on first use; `null` while the platform has not answered and
349
+ * nothing was resumed.
350
+ */
277
351
  id(): Promise<string | null>;
352
+ private open;
278
353
  /**
279
354
  * The platform's verdict on a payment about to be presented. Asked once
280
355
  * per call id: a host that re-runs its approval step reads the same
@@ -305,4 +380,4 @@ declare class Session {
305
380
  private static callOf;
306
381
  }
307
382
 
308
- export { BelticApiError as B, ChainRejectedError as C, type DecideOptions as D, type HumanDecisionInput as H, Session as S, Decision as a, type SessionOptions as b };
383
+ export { ApiClient as A, BelticApiError as B, ChainRejectedError as C, type DecideOptions as D, type HumanDecisionInput as H, Session as S, Decision as a, type SessionOptions as b };
@@ -1,10 +1,9 @@
1
1
  import { RoutesConfig, x402ResourceServer } from '@x402/core/server';
2
2
  import { MiddlewareHandler } from 'hono';
3
- import { B as Beltic } from '../client-CgCjOrRP.js';
4
- export { a as attachX402 } from '../adapter-AjCgj-KM.js';
5
- import '../index-IfY4XCvJ.js';
3
+ import { B as Beltic } from '../client-DFZL4Pt3.js';
4
+ import '../index-CBUSXzgG.js';
6
5
  import 'zod';
7
- import '../session-Dcof4UIn.js';
6
+ import '../session-DTIzd1EQ.js';
8
7
 
9
8
  /** Seller half for hono: `@x402/hono`'s payment middleware with the Beltic hooks attached. */
10
9
 
package/dist/x402/hono.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  attachX402
3
- } from "../chunk-IUWC6HT5.js";
4
- import "../chunk-M4I3FGZG.js";
5
- import "../chunk-FQDHFTVR.js";
6
- import "../chunk-77D74TWX.js";
3
+ } from "../chunk-P3VZNH5W.js";
4
+ import "../chunk-DI3LZR65.js";
5
+ import "../chunk-MWXXX35V.js";
6
+ import "../chunk-PDE55ZZV.js";
7
7
 
8
8
  // src/x402/hono.ts
9
9
  import {
@@ -16,6 +16,5 @@ function belticPaymentMiddleware(beltic, routes, server) {
16
16
  return paymentMiddlewareFromHTTPServer(http);
17
17
  }
18
18
  export {
19
- attachX402,
20
19
  belticPaymentMiddleware
21
20
  };
@@ -1,9 +1,10 @@
1
- export { a as attachX402 } from '../adapter-AjCgj-KM.js';
2
- import { S as Session } from '../session-Dcof4UIn.js';
3
- import { p as DeclaredIntent, a7 as PaymentSummary } from '../index-IfY4XCvJ.js';
4
- import '@x402/core/server';
5
- import '../client-CgCjOrRP.js';
1
+ import { x402ResourceServer, x402HTTPResourceServer } from '@x402/core/server';
2
+ import { B as Beltic } from '../client-DFZL4Pt3.js';
3
+ import '../index-CBUSXzgG.js';
6
4
  import 'zod';
5
+ import '../session-DTIzd1EQ.js';
6
+
7
+ declare function attachX402(beltic: Beltic, server: x402ResourceServer, http?: x402HTTPResourceServer): void;
7
8
 
8
9
  /**
9
10
  * Session binding on the x402 rail (Fraud SDK RFC › Protocol Adapter — x402:
@@ -13,75 +14,4 @@ import 'zod';
13
14
  declare const SESSION_EXTENSION = "beltic.sessionId";
14
15
  declare const SESSION_HEADER = "Beltic-Session-Id";
15
16
 
16
- /**
17
- * Buyer half › the x402 fetch wrapper. Sits *inside* the agent's paying
18
- * fetch (e.g. `wrapFetchWithPayment(belticFetch(session))`), so it sees the
19
- * 402 challenge → `payment.requested`, and the retry carrying the payment
20
- * → `payment.presented`, into which it injects the session binding
21
- * (GAP-30). It never pays and never decides.
22
- *
23
- * Before a request that presents payment leaves, the buffered evidence is
24
- * flushed: the seller will evaluate as soon as it sees the payment, and
25
- * the platform must already hold the buyer's side of the story (GAP-66).
26
- *
27
- * Only x402 v2 is read — `PAYMENT-REQUIRED` header, `PAYMENT-SIGNATURE`
28
- * retry, binding in `extensions` (GAP-72). The header codec is base64
29
- * JSON, kept here so a buyer needs no `@x402/*` package to be observed.
30
- */
31
-
32
- /**
33
- * The paying fetch, observed. A request made while the session has no
34
- * stream (the platform could not open one, GAP-70) goes through the inner
35
- * fetch unrecorded.
36
- */
37
- declare function belticFetch(session: Session, inner?: typeof globalThis.fetch): typeof globalThis.fetch;
38
-
39
- /**
40
- * The declared intent for an x402 mandate (Fraud SDK RFC › Session ›
41
- * `intent.declared`). The cap must be in the currency the rail's moments
42
- * carry — `<network>/<asset>`, atomic units (GAP-49) — or the platform's
43
- * spend detectors compare two currencies and never meet; this is the one
44
- * place a buyer spells that. Everything else is the protocol's own shape.
45
- */
46
-
47
- interface X402IntentInput {
48
- mandate: string;
49
- network: string;
50
- asset: string;
51
- /** Atomic units of `asset`, as x402 carries amounts — a decimal string or a bigint, never a float. */
52
- maxAmount: string | bigint;
53
- validUntil: string | Date;
54
- merchantAllowlist?: string[] | undefined;
55
- }
56
- declare function x402Intent(input: X402IntentInput): DeclaredIntent;
57
-
58
- /**
59
- * x402 artifacts → protocol moments (Fraud SDK RFC › Protocol Adapter —
60
- * x402). The moment is normalized (payee, amount, payer) so both sides of
61
- * a purchase compare; the artifact travels whole in `raw`. For x402 the
62
- * currency is `<network>/<asset>` (GAP-49) and the value is the atomic
63
- * amount as the protocol carries it — `x402Summary` gives a buyer the same
64
- * normalization for the payment it is about to evaluate, so what it asks
65
- * about and what the wrapper records are one and the same.
66
- */
67
-
68
- /**
69
- * The minimum an `accepts` entry needs to become a moment; unknown parts
70
- * are named, never dropped.
71
- */
72
- interface AcceptsLike {
73
- payTo?: string | undefined;
74
- amount?: string | undefined;
75
- network?: string | undefined;
76
- asset?: string | undefined;
77
- }
78
- /**
79
- * The one normalization of an x402 `accepts` entry: the payment in the
80
- * shape `evaluate` takes, with the payer as `payerOf` would read it. Every
81
- * moment below is this plus its artifact and `raw`.
82
- */
83
- declare function x402Summary(accepts: AcceptsLike | undefined, opts?: {
84
- payer?: string | undefined;
85
- }): PaymentSummary;
86
-
87
- export { type AcceptsLike, SESSION_EXTENSION, SESSION_HEADER, type X402IntentInput, belticFetch, x402Intent, x402Summary };
17
+ export { SESSION_EXTENSION, SESSION_HEADER, attachX402 };
@@ -1,77 +1,14 @@
1
+ import {
2
+ attachX402
3
+ } from "../chunk-P3VZNH5W.js";
1
4
  import {
2
5
  SESSION_EXTENSION,
3
- SESSION_HEADER,
4
- attachX402,
5
- x402Currency,
6
- x402Moments,
7
- x402Summary
8
- } from "../chunk-IUWC6HT5.js";
9
- import "../chunk-M4I3FGZG.js";
10
- import "../chunk-FQDHFTVR.js";
11
- import "../chunk-77D74TWX.js";
12
-
13
- // src/x402/fetch.ts
14
- var BASE64 = /^[A-Za-z0-9+/]*={0,2}$/;
15
- function belticFetch(session, inner = globalThis.fetch) {
16
- return async (input, init) => {
17
- const stream = await session.stream();
18
- if (!stream) return inner(input, init);
19
- const headers = new Headers(
20
- init?.headers ?? (input instanceof Request ? input.headers : void 0)
21
- );
22
- headers.set(SESSION_HEADER, stream.id);
23
- const signature = headers.get("PAYMENT-SIGNATURE");
24
- const payload = signature ? decodeHeader(signature) : null;
25
- if (payload) {
26
- const bound = {
27
- ...payload,
28
- extensions: { ...payload.extensions, [SESSION_EXTENSION]: stream.id }
29
- };
30
- headers.set("PAYMENT-SIGNATURE", encodeHeader(bound));
31
- await stream.emit("payment.presented", x402Moments.payload(bound));
32
- await stream.flush();
33
- }
34
- const res = await inner(input, { ...init, headers });
35
- if (res.status !== 402) return res;
36
- const required = challengeOf(res);
37
- if (required) await stream.emit("payment.requested", x402Moments.required(required));
38
- return res;
39
- };
40
- }
41
- function decodeHeader(value) {
42
- if (!BASE64.test(value)) return null;
43
- try {
44
- const parsed = JSON.parse(Buffer.from(value, "base64").toString("utf8"));
45
- return parsed && typeof parsed === "object" ? parsed : null;
46
- } catch {
47
- return null;
48
- }
49
- }
50
- function encodeHeader(value) {
51
- return Buffer.from(JSON.stringify(value), "utf8").toString("base64");
52
- }
53
- function challengeOf(res) {
54
- const header = res.headers.get("PAYMENT-REQUIRED");
55
- return header ? decodeHeader(header) : null;
56
- }
57
-
58
- // src/x402/intent.ts
59
- function x402Intent(input) {
60
- return {
61
- mandate: input.mandate,
62
- maxAmount: {
63
- value: input.maxAmount.toString(),
64
- currency: x402Currency(input.network, input.asset)
65
- },
66
- validUntil: new Date(input.validUntil).toISOString(),
67
- ...input.merchantAllowlist ? { merchantAllowlist: input.merchantAllowlist } : {}
68
- };
69
- }
6
+ SESSION_HEADER
7
+ } from "../chunk-DI3LZR65.js";
8
+ import "../chunk-MWXXX35V.js";
9
+ import "../chunk-PDE55ZZV.js";
70
10
  export {
71
11
  SESSION_EXTENSION,
72
12
  SESSION_HEADER,
73
- attachX402,
74
- belticFetch,
75
- x402Intent,
76
- x402Summary
13
+ attachX402
77
14
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@belticlabs/agent-risk-sdk",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "The Beltic Agent Risk SDK — one client, two halves: instrument the buyer agent (AI SDK, x402 fetch) and guard the seller boundary (x402 over hono, evaluate).",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -1,6 +0,0 @@
1
- import { x402ResourceServer, x402HTTPResourceServer } from '@x402/core/server';
2
- import { B as Beltic } from './client-CgCjOrRP.js';
3
-
4
- declare function attachX402(beltic: Beltic, server: x402ResourceServer, http?: x402HTTPResourceServer): void;
5
-
6
- export { attachX402 as a };
@@ -1,29 +0,0 @@
1
- // src/core/json.ts
2
- function toJson(value) {
3
- if (value === null || value === void 0) return null;
4
- if (typeof value === "string" || typeof value === "boolean") return value;
5
- if (typeof value === "number") return Number.isFinite(value) ? value : null;
6
- if (typeof value === "bigint") return value.toString();
7
- if (value instanceof Uint8Array) return { $bytes: Buffer.from(value).toString("base64") };
8
- if (value instanceof Date) return value.toISOString();
9
- if (value instanceof URL) return value.toString();
10
- if (Array.isArray(value)) return value.map(toJson);
11
- if (typeof value === "object") {
12
- const out = {};
13
- for (const [k, v] of Object.entries(value)) {
14
- if (v === void 0 || typeof v === "function") continue;
15
- out[k] = toJson(v);
16
- }
17
- return out;
18
- }
19
- return null;
20
- }
21
- function toJsonObject(value) {
22
- const j = toJson(value);
23
- return j && typeof j === "object" && !Array.isArray(j) ? j : { value: j };
24
- }
25
-
26
- export {
27
- toJson,
28
- toJsonObject
29
- };