agent402-client 0.8.20 → 0.8.21

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/index.js +12 -4
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -269,7 +269,7 @@ that runs as one.
269
269
 
270
270
  | Method | What |
271
271
  |---|---|
272
- | `new Agent402({ baseUrl?, fetch?, x402Client?, creditsKey?, gateway?, cache?, fetchImpl?, maxPerCallUsd?, dailyLimitUsd?, maxPerHostUsd?, payNetworks?, maxResponseBytes?, outputValidator?, respondAsync?, asyncTimeoutMs?, onProgress? })` | `fetch` is your x402- or MPP-wrapped fetch for paid tools (optional); `x402Client` is the `@x402/core` client that `fetch` wraps, so the caps are enforced on the payment that is signed (see below); `payNetworks` (for example `["base"]`, the names `withNetworkPreference` takes) tells the caps which chains a pre-wrapped `fetch` without an `x402Client` pays on, so a call is counted at the dearest option on those chains (when none of a 402's options is on them, the dearest of all counts); `creditsKey` is a prepaid credits key (`a402_...`) used for paid tools when no `fetch` is given; `gateway` (`{ signer, networks? }`) pays the Circle Gateway batched accept where a 402 offers one, from the signer's Gateway deposit (see above); `cache` (default `true`) memoizes deterministic results; the three USD caps set optional spending limits (see below); `maxResponseBytes` (default 32MB, `null` to disable) refuses an oversized response body before it is parsed; `outputValidator` binds a caller-supplied delivery check; `respondAsync` (default `"auto"`), `asyncTimeoutMs` (default 15 minutes) and `onProgress` control slow routes run as jobs (see above) |
272
+ | `new Agent402({ baseUrl?, fetch?, x402Client?, creditsKey?, gateway?, cache?, fetchImpl?, maxPerCallUsd?, dailyLimitUsd?, maxPerHostUsd?, payNetworks?, maxResponseBytes?, outputValidator?, respondAsync?, asyncTimeoutMs?, onProgress?, userAgent? })` | `fetch` is your x402- or MPP-wrapped fetch for paid tools (optional); `x402Client` is the `@x402/core` client that `fetch` wraps, so the caps are enforced on the payment that is signed (see below); `payNetworks` (for example `["base"]`, the names `withNetworkPreference` takes) tells the caps which chains a pre-wrapped `fetch` without an `x402Client` pays on, so a call is counted at the dearest option on those chains (when none of a 402's options is on them, the dearest of all counts); `creditsKey` is a prepaid credits key (`a402_...`) used for paid tools when no `fetch` is given; `gateway` (`{ signer, networks? }`) pays the Circle Gateway batched accept where a 402 offers one, from the signer's Gateway deposit (see above); `cache` (default `true`) memoizes deterministic results; the three USD caps set optional spending limits (see below); `maxResponseBytes` (default 32MB, `null` to disable) refuses an oversized response body before it is parsed; `outputValidator` binds a caller-supplied delivery check; `respondAsync` (default `"auto"`), `asyncTimeoutMs` (default 15 minutes) and `onProgress` control slow routes run as jobs (see above); `userAgent` (`"name/version"`) is a calling package's own product token, sent before `agent402-client/<version>` in the User-Agent |
273
273
  | `await a.find(task, { k = 5 })` | Resolve a plain-language task to the best-matching tools on **this host** (route, price, schema, example) |
274
274
  | `await a.route(task, { k?, include?, network? })` | Cross-seller Smart Order Router: rank eligible/routable seller rows from the host's current index (free, read-only; opaque results may include server-reported `executeVia`) |
275
275
  | `await a.findWorkflows(task, { k = 2 })` | Resolve a task to matching multi-tool workflow templates (skill packs) |
package/index.js CHANGED
@@ -30,8 +30,13 @@ export { AsyncJobPendingError } from "./async-job.js";
30
30
  // `User-Agent: agent402-client/<version>` - a standard header, no extra
31
31
  // network calls - so a seller can attribute traffic (and settled payments)
32
32
  // to this SDK. Product token only; nothing about the caller rides along.
33
- const VERSION = "0.8.20";
33
+ const VERSION = "0.8.21";
34
34
  const USER_AGENT = `agent402-client/${VERSION}`;
35
+ // A package built on this SDK (an adapter) names itself first: its own
36
+ // product token, then this one. Anything that is not one well-formed token
37
+ // is ignored and the SDK's own token is sent alone.
38
+ const PRODUCT_TOKEN_RE = /^[A-Za-z0-9.-]{1,40}\/[A-Za-z0-9.-]{1,20}$/;
39
+ const userAgentOf = (product) => (typeof product === "string" && PRODUCT_TOKEN_RE.test(product) ? `${product} ${USER_AGENT}` : USER_AGENT);
35
40
  // 32MB: about a hundred times any realistic response from this catalog (the
36
41
  // largest is a base64 image at a few MB), so it cannot break a legitimate
37
42
  // caller, while still stopping the class it exists for. A ceiling that is off
@@ -120,6 +125,8 @@ export class Agent402 {
120
125
  * @param {typeof fetch} [opts.fetch] an x402-wrapped fetch for wallet-only tools (optional)
121
126
  * @param {boolean} [opts.cache=true] cache results in memory (deterministic tools)
122
127
  * @param {typeof fetch} [opts.fetchImpl] plain fetch (defaults to global fetch through distrustFetch)
128
+ * @param {string} [opts.userAgent] a calling package's own product token ("name/version"),
129
+ * sent before agent402-client's in the User-Agent
123
130
  * @param {boolean} [opts.tlsDistrust=true] send the default fetch through distrustFetch (refuses a TLS
124
131
  * chain through a distrusted intermediate CA); false sends it as is
125
132
  * @param {number} [opts.maxPerCallUsd] hard ceiling on a single paid call (USD); over → SpendingLimitError before paying
@@ -156,7 +163,8 @@ export class Agent402 {
156
163
  constructor({ baseUrl = "https://agent402.tools", fetch: payFetch, cache = true, fetchImpl = undefined, tlsDistrust = true,
157
164
  maxPerCallUsd = null, dailyLimitUsd = null, maxPerHostUsd = null, creditsKey = null, x402Client = null, payNetworks = null,
158
165
  maxResponseBytes = DEFAULT_MAX_RESPONSE_BYTES, outputValidator = null,
159
- respondAsync = "auto", asyncTimeoutMs = DEFAULT_ASYNC_TIMEOUT_MS, onProgress = null, gateway = null } = {}) {
166
+ respondAsync = "auto", asyncTimeoutMs = DEFAULT_ASYNC_TIMEOUT_MS, onProgress = null, gateway = null, userAgent = null } = {}) {
167
+ this.userAgent = userAgentOf(userAgent);
160
168
  this.respondAsync = respondAsync;
161
169
  this.gateway = normalizeGateway(gateway);
162
170
  this.asyncTimeoutMs = numOrNull(asyncTimeoutMs) ?? DEFAULT_ASYNC_TIMEOUT_MS;
@@ -171,7 +179,7 @@ export class Agent402 {
171
179
  this.payFetch = payFetch || null;
172
180
  // Wrap the plain fetch so every request identifies the SDK (see USER_AGENT
173
181
  // above). Caller-supplied init.headers still win on a key collision.
174
- this.f = (url, init = {}) => fetchImpl(url, { ...init, headers: { "User-Agent": USER_AGENT, ...(init.headers || {}) } });
182
+ this.f = (url, init = {}) => fetchImpl(url, { ...init, headers: { "User-Agent": this.userAgent, ...(init.headers || {}) } });
175
183
  this._catalog = null;
176
184
  // The wait between shed-503 retries of a discovery read (tests replace it).
177
185
  this._sleep = sleepMs;
@@ -511,7 +519,7 @@ export class Agent402 {
511
519
  const send = async (extraHeaders = {}, useFetch = this.f, { paid = false } = {}) => {
512
520
  // UA set here too (not only in the this.f wrapper) so the x402 payFetch
513
521
  // path - the one that settles real payments - always carries it.
514
- const headers = { "User-Agent": USER_AGENT, "Idempotency-Key": idem, ...extraHeaders };
522
+ const headers = { "User-Agent": this.userAgent, "Idempotency-Key": idem, ...extraHeaders };
515
523
  let url = `${this.baseUrl}${tool.path}`;
516
524
  // A request that can carry a payment never follows a redirect: followed,
517
525
  // it would answer a 402 from another origin with a signature to that
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent402-client",
3
- "version": "0.8.20",
3
+ "version": "0.8.21",
4
4
  "description": "Agent402 buyer SDK: resolve a task to a tool across 500+ pay-per-call endpoints and call it with payment handled - free via proof-of-work, or over x402 or MPP (a stock mppx fetch works) with a wallet you keep; the buy side of Agentic Finance. Caching, idempotent retries (Idempotency-Key), non-custodial, zero dependencies.",
5
5
  "type": "module",
6
6
  "main": "index.js",