@belticlabs/agent-risk-sdk 0.6.0 → 0.7.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 { m as EvaluateOutput, D as Decision$1, y as JsonObject, n as EventResult, r as EvidenceEvent, u as EvidenceSource, T as PromptBase, a4 as WireEvidenceKind, P as PayloadByKind, J as JsonValue, a2 as ToolCallStartPayload, Y as SessionClosePayload, h as DeclaredIntent, N as PaymentSummary, K as PaymentMomentPayload } from './index-DAVKGJs5.js';
2
2
 
3
3
  /**
4
4
  * The platform's verdict on one payment as a value the host can ask
@@ -69,18 +69,21 @@ interface AgentIdentity {
69
69
  }
70
70
 
71
71
  /**
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.
72
+ * One instrumented call = a `*.start` event, the work, a `*.end` event
73
+ * carrying the outcome or the error (GAP-07 correlates them by `callId`).
74
+ * `openCall` is the span — `Stream.llmCall` and `Stream.toolCall` open
75
+ * one — and `recordCall` runs the work inside it. The AI middleware, the
76
+ * tool wrapper and a host's own tool loop all record the same way.
82
77
  */
83
78
 
79
+ interface CallSpan {
80
+ readonly callId: string;
81
+ /** Resolves once `*.start` is sequenced; `end` and `fail` wait for it. */
82
+ readonly opened: Promise<boolean>;
83
+ end(outcome?: JsonObject): Promise<boolean>;
84
+ fail(error: unknown, outcome?: JsonObject): Promise<boolean>;
85
+ }
86
+
84
87
  declare class ChainRejectedError extends Error {
85
88
  readonly sessionId: string;
86
89
  readonly source: string;
@@ -89,10 +92,17 @@ declare class ChainRejectedError extends Error {
89
92
  cause?: unknown;
90
93
  });
91
94
  }
95
+ /** Which chains a `flush` sends: one session's, or every chain of the process. */
96
+ interface FlushScope {
97
+ sessionId: string;
98
+ }
92
99
  declare class Transport {
93
100
  private readonly api;
94
101
  private readonly chains;
102
+ private readonly waiting;
103
+ private running;
95
104
  private buffered;
105
+ private bufferedBytes;
96
106
  private timer;
97
107
  private closed;
98
108
  constructor(api: ApiClient);
@@ -103,21 +113,41 @@ declare class Transport {
103
113
  * invalid payload) is a fault of the client and throws.
104
114
  */
105
115
  static outage(err: unknown): boolean;
106
- get size(): number;
107
- hasRoom(): boolean;
116
+ /** The bytes the platform will measure for an event with this payload (GAP-59), known before a `seq` is spent. */
117
+ static measure(payload: unknown): number;
118
+ /** Whether the platform would take an event of this size at all. */
119
+ static fits(bytes: number): boolean;
120
+ hasRoom(bytes: number): boolean;
108
121
  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>;
122
+ /** Whether the platform ended the session under this chain (GAP-85). */
123
+ ended(sessionId: string, source: string): boolean;
124
+ /** Callers check `hasRoom(bytes)` first and assign `seq` only then (GAP-38). */
125
+ enqueue(ev: EvidenceEvent, bytes: number): void;
126
+ /**
127
+ * One attempt per chain, now — a chain waiting out its backoff included;
128
+ * resolves once every attempt settled. With a scope, only that session's
129
+ * chains (GAP-88).
130
+ */
131
+ flush(scope?: FlushScope): Promise<void>;
113
132
  close(): Promise<void>;
114
133
  private schedule;
115
134
  private unschedule;
116
- /** A chain waiting out its backoff is left alone unless forced: only `flush` cuts a backoff short. */
135
+ /**
136
+ * Queues the chain for a delivery slot — at the front when forced. A
137
+ * chain waiting out its backoff is left alone unless forced: only
138
+ * `flush` cuts a backoff short.
139
+ */
117
140
  private deliver;
141
+ private promote;
142
+ private pump;
143
+ /** The head of the queue that fits one batch: by count or by bytes, whichever comes first, and never empty. */
144
+ private static batchOf;
118
145
  /** Batches until the chain drains; a retryable failure schedules the next attempt and returns. */
119
146
  private attempt;
147
+ private release;
148
+ private drop;
120
149
  private halt;
150
+ private end;
121
151
  }
122
152
 
123
153
  /**
@@ -128,9 +158,15 @@ declare class Transport {
128
158
  *
129
159
  * `seq` is handed out only when the transport has room for the event
130
160
  * (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.
161
+ * is preceded by a `transport.gap` that counts the drops, and how many of
162
+ * them the platform would have refused as too large (GAP-87); the size is
163
+ * measured here, once, before the seq is spent. Payloads ship whole
164
+ * (GAP-33) — except the prompt of a model call, which ships as a delta
165
+ * against the last one on the chain (GAP-89; `PromptLedger`). An outage
166
+ * never reaches `emit`: the transport waits it out (GAP-70); what throws
167
+ * here is a chain the platform rejected. A session the platform closed or
168
+ * expired is over, not broken: `emit` answers `false` and the conversation
169
+ * continues in a fresh stream (GAP-85).
134
170
  */
135
171
 
136
172
  /** Who created the session — the seller half treats a bound session as buyer-born. */
@@ -138,9 +174,18 @@ type StreamBorn = 'buyer' | 'seller';
138
174
  interface StreamDeps {
139
175
  transport: Transport;
140
176
  signer?: Signer | undefined;
177
+ /** The conversation's last prompt, when resuming one: what the first model call ships a delta against (GAP-89). */
178
+ prompt?: PromptBase | undefined;
141
179
  /** Called once the stream closed, so the registry can forget it. */
142
180
  onClosed?: ((stream: Stream) => void) | undefined;
143
181
  }
182
+ /** What the host knows of a model call before it runs: the provider-level options, prompt included (GAP-57). */
183
+ interface LlmCallInput {
184
+ callId: string;
185
+ provider: string;
186
+ modelId: string;
187
+ params: Record<string, JsonValue>;
188
+ }
144
189
  /**
145
190
  * One tool call as a span: `tool_call.start` now, `tool_call.end` with the
146
191
  * outcome and the elapsed time when the host reports it.
@@ -159,25 +204,41 @@ interface ToolCallSpan {
159
204
  declare class Stream {
160
205
  private readonly deps;
161
206
  readonly id: string;
207
+ /** The conversation this session belongs to — the root's id (GAP-84). */
208
+ readonly conversationId: string;
162
209
  readonly source: EvidenceSource;
163
210
  readonly born: StreamBorn;
164
211
  private chain;
212
+ private readonly ledger;
165
213
  private building;
166
214
  private dropped;
215
+ private oversized;
167
216
  private droppedFirstTs;
168
217
  private droppedLastTs;
169
218
  private closed;
170
- constructor(deps: StreamDeps, id: string, source: EvidenceSource, born: StreamBorn);
219
+ constructor(deps: StreamDeps, id: string,
220
+ /** The conversation this session belongs to — the root's id (GAP-84). */
221
+ conversationId: string, source: EvidenceSource, born: StreamBorn);
222
+ /** Closed by this side, or ended by the platform (GAP-85). */
171
223
  get isClosed(): boolean;
172
224
  /**
173
225
  * Resolves once the event is sequenced and buffered — not once it is
174
226
  * acknowledged. `false` when the event was dropped for lack of room.
175
227
  */
176
228
  emit<K extends WireEvidenceKind>(kind: K, payload: PayloadByKind[K]): Promise<boolean>;
229
+ /** What the drops since the last accepted event add up to (GAP-38/87). */
230
+ private gap;
231
+ /**
232
+ * A model call as a span: `llm_call.start` now, with the prompt as a
233
+ * delta against the last one on this chain (GAP-89), `llm_call.end` when
234
+ * the host reports the result. A start that never left (dropped) forgets
235
+ * the ledger, so the next call ships its prompt whole.
236
+ */
237
+ llmCall(call: LlmCallInput): CallSpan;
177
238
  /** The tool call whose `execute` the host runs itself; see `ToolCallSpan`. */
178
239
  toolCall(call: ToolCallStartPayload): ToolCallSpan;
179
240
  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). */
241
+ /** Read-your-writes for this session's chains, and only them (GAP-16/66/88). */
181
242
  flush(): Promise<void>;
182
243
  /** Serialized: two concurrent emits get consecutive seqs, never the same one. */
183
244
  private next;
@@ -187,16 +248,18 @@ declare class Stream {
187
248
  * The registry of evidence streams, one object per (session, source) per
188
249
  * process: a chain's head lives in it, so two objects for the same chain
189
250
  * 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).
251
+ * process never continues a chain it did not start — it resumes the
252
+ * conversation in a fresh one (GAP-67/84).
191
253
  *
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
254
+ * The buyer half opens AGENT_TRACE sessions, new or resuming a
255
+ * conversation, and announces them with `session.open` (seq 0) and
194
256
  * `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).
257
+ * open — an outage — resolves `null` for every caller during
258
+ * `OPEN_RETRY_MS`, so the host runs without evidence instead of paying a
259
+ * failed request on every step (GAP-70); a refused one (4xx) throws, and
260
+ * the next call tries again. A resumed conversation's stream starts from
261
+ * the prompt base the platform answered (GAP-89). The seller half attaches
262
+ * to a bound session or opens its own INTERNAL_NETWORK one (GAP-13).
200
263
  */
201
264
 
202
265
  interface StartInput {
@@ -207,6 +270,10 @@ interface StartInput {
207
270
  } | undefined;
208
271
  attestations?: JsonObject | undefined;
209
272
  }
273
+ interface OpenInput extends StartInput {
274
+ /** The conversation to continue: any session id of it (GAP-84). */
275
+ resume?: string | undefined;
276
+ }
210
277
  interface StreamsDeps {
211
278
  api: ApiClient;
212
279
  transport: Transport;
@@ -216,20 +283,17 @@ interface StreamsDeps {
216
283
  declare class Streams {
217
284
  private readonly deps;
218
285
  private readonly attached;
219
- /** Buyer streams by the host's own key (GAP-71). */
220
- private readonly opened;
221
286
  private retryAt;
222
287
  constructor(deps: StreamsDeps);
223
288
  /**
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.
289
+ * Buyer half: a fresh AGENT_TRACE stream — a new conversation, or a new
290
+ * session of the one `resume` names. `null` while the platform is out.
227
291
  */
228
- open(key: string, input?: StartInput): Promise<Stream | null>;
292
+ open(input?: OpenInput, onClosed?: () => void): Promise<Stream | null>;
229
293
  /** Seller half: emit INTERNAL_NETWORK evidence into a session the buyer bound, or open a seller-born one. */
230
294
  ensure(sessionId?: string | null): Promise<Stream>;
231
- private forget;
232
- private openFresh;
295
+ /** Whether the platform refused this stream's chain: its next `emit` throws (GAP-85). */
296
+ halted(stream: Stream): boolean;
233
297
  private create;
234
298
  private attach;
235
299
  }
@@ -255,16 +319,19 @@ interface DecideOptions {
255
319
  }
256
320
  interface SessionDeps {
257
321
  streams: Streams;
258
- evaluate: (sessionId: string, payment: PaymentSummary) => Promise<Decision>;
322
+ evaluate: (sessionId: string, payment: PaymentSummary, callId?: string) => Promise<Decision>;
323
+ /** Called once the platform answered with the conversation id, so the registry can key the handle by it. */
324
+ onOpened: (session: Session, conversationId: string) => void;
259
325
  /** Called once the session closed, so the registry forgets it. */
260
326
  onClosed: (session: Session) => void;
261
327
  }
262
328
  declare class Session {
263
329
  private readonly deps;
264
- readonly key: string;
265
330
  private readonly opts;
266
331
  private opened;
267
332
  private current;
333
+ /** The conversation id: what was resumed, then what the platform answered. */
334
+ private conversationId;
268
335
  /** JCS hash of the mandate on the chain, and of the one the options carried. */
269
336
  private declared;
270
337
  private readonly openedWith;
@@ -272,9 +339,14 @@ declare class Session {
272
339
  private timer;
273
340
  private readonly calls;
274
341
  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. */
342
+ constructor(deps: SessionDeps, opts?: SessionOptions, resume?: string | null);
343
+ /**
344
+ * The conversation id — what the host stores and resumes with (GAP-84).
345
+ * Opened on first use; `null` while the platform has not answered and
346
+ * nothing was resumed.
347
+ */
277
348
  id(): Promise<string | null>;
349
+ private open;
278
350
  /**
279
351
  * The platform's verdict on a payment about to be presented. Asked once
280
352
  * per call id: a host that re-runs its approval step reads the same
@@ -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-Xn9M58OJ.js';
4
+ import '../index-DAVKGJs5.js';
6
5
  import 'zod';
7
- import '../session-Dcof4UIn.js';
6
+ import '../session-DAN29XoB.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,10 @@
1
1
  import {
2
2
  attachX402
3
- } from "../chunk-IUWC6HT5.js";
3
+ } from "../chunk-HI656UWG.js";
4
4
  import "../chunk-M4I3FGZG.js";
5
5
  import "../chunk-FQDHFTVR.js";
6
- import "../chunk-77D74TWX.js";
6
+ import "../chunk-UXXSE643.js";
7
+ import "../chunk-FNU4CRJJ.js";
7
8
 
8
9
  // src/x402/hono.ts
9
10
  import {
@@ -16,6 +17,5 @@ function belticPaymentMiddleware(beltic, routes, server) {
16
17
  return paymentMiddlewareFromHTTPServer(http);
17
18
  }
18
19
  export {
19
- attachX402,
20
20
  belticPaymentMiddleware
21
21
  };
@@ -1,10 +1,11 @@
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-Xn9M58OJ.js';
3
+ import { S as Session } from '../session-DAN29XoB.js';
4
+ import { h as DeclaredIntent, N as PaymentSummary } from '../index-DAVKGJs5.js';
6
5
  import 'zod';
7
6
 
7
+ declare function attachX402(beltic: Beltic, server: x402ResourceServer, http?: x402HTTPResourceServer): void;
8
+
8
9
  /**
9
10
  * Session binding on the x402 rail (Fraud SDK RFC › Protocol Adapter — x402:
10
11
  * "`PAYMENT-SIGNATURE` extension `beltic.sessionId`"). Where exactly it
@@ -13,22 +14,6 @@ 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
17
  /**
33
18
  * The paying fetch, observed. A request made while the session has no
34
19
  * stream (the platform could not open one, GAP-70) goes through the inner
@@ -84,4 +69,4 @@ declare function x402Summary(accepts: AcceptsLike | undefined, opts?: {
84
69
  payer?: string | undefined;
85
70
  }): PaymentSummary;
86
71
 
87
- export { type AcceptsLike, SESSION_EXTENSION, SESSION_HEADER, type X402IntentInput, belticFetch, x402Intent, x402Summary };
72
+ export { type AcceptsLike, SESSION_EXTENSION, SESSION_HEADER, type X402IntentInput, attachX402, belticFetch, x402Intent, x402Summary };
@@ -2,16 +2,42 @@ import {
2
2
  SESSION_EXTENSION,
3
3
  SESSION_HEADER,
4
4
  attachX402,
5
- x402Currency,
6
5
  x402Moments,
7
6
  x402Summary
8
- } from "../chunk-IUWC6HT5.js";
7
+ } from "../chunk-HI656UWG.js";
9
8
  import "../chunk-M4I3FGZG.js";
10
9
  import "../chunk-FQDHFTVR.js";
11
- import "../chunk-77D74TWX.js";
10
+ import "../chunk-UXXSE643.js";
11
+ import {
12
+ Money
13
+ } from "../chunk-FNU4CRJJ.js";
12
14
 
13
15
  // src/x402/fetch.ts
14
- var BASE64 = /^[A-Za-z0-9+/]*={0,2}$/;
16
+ import { z } from "zod";
17
+ var Base64Json = z.string().regex(/^[A-Za-z0-9+/]*={0,2}$/).transform((value, ctx) => {
18
+ try {
19
+ return JSON.parse(Buffer.from(value, "base64").toString("utf8"));
20
+ } catch {
21
+ ctx.addIssue({ code: "custom", message: "not base64 JSON" });
22
+ return z.NEVER;
23
+ }
24
+ });
25
+ var Accepts = z.looseObject({
26
+ payTo: z.string().optional().catch(void 0),
27
+ amount: z.string().optional().catch(void 0),
28
+ network: z.string().optional().catch(void 0),
29
+ asset: z.string().optional().catch(void 0)
30
+ });
31
+ var PaymentRequired = Base64Json.pipe(
32
+ z.looseObject({ accepts: z.array(Accepts).optional().catch(void 0) })
33
+ );
34
+ var PaymentPayload = Base64Json.pipe(
35
+ z.looseObject({
36
+ accepted: Accepts.optional().catch(void 0),
37
+ payload: z.record(z.string(), z.unknown()).optional().catch(void 0),
38
+ extensions: z.record(z.string(), z.unknown()).optional().catch(void 0)
39
+ })
40
+ );
15
41
  function belticFetch(session, inner = globalThis.fetch) {
16
42
  return async (input, init) => {
17
43
  const stream = await session.stream();
@@ -20,8 +46,7 @@ function belticFetch(session, inner = globalThis.fetch) {
20
46
  init?.headers ?? (input instanceof Request ? input.headers : void 0)
21
47
  );
22
48
  headers.set(SESSION_HEADER, stream.id);
23
- const signature = headers.get("PAYMENT-SIGNATURE");
24
- const payload = signature ? decodeHeader(signature) : null;
49
+ const payload = PaymentPayload.safeParse(headers.get("PAYMENT-SIGNATURE")).data;
25
50
  if (payload) {
26
51
  const bound = {
27
52
  ...payload,
@@ -33,36 +58,20 @@ function belticFetch(session, inner = globalThis.fetch) {
33
58
  }
34
59
  const res = await inner(input, { ...init, headers });
35
60
  if (res.status !== 402) return res;
36
- const required = challengeOf(res);
61
+ const required = PaymentRequired.safeParse(res.headers.get("PAYMENT-REQUIRED")).data;
37
62
  if (required) await stream.emit("payment.requested", x402Moments.required(required));
38
63
  return res;
39
64
  };
40
65
  }
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
66
  function encodeHeader(value) {
51
67
  return Buffer.from(JSON.stringify(value), "utf8").toString("base64");
52
68
  }
53
- function challengeOf(res) {
54
- const header = res.headers.get("PAYMENT-REQUIRED");
55
- return header ? decodeHeader(header) : null;
56
- }
57
69
 
58
70
  // src/x402/intent.ts
59
71
  function x402Intent(input) {
60
72
  return {
61
73
  mandate: input.mandate,
62
- maxAmount: {
63
- value: input.maxAmount.toString(),
64
- currency: x402Currency(input.network, input.asset)
65
- },
74
+ maxAmount: Money.x402(input.network, input.asset, input.maxAmount).toAmount(),
66
75
  validUntil: new Date(input.validUntil).toISOString(),
67
76
  ...input.merchantAllowlist ? { merchantAllowlist: input.merchantAllowlist } : {}
68
77
  };
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.7.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 };