agent402-mcp 0.13.17 → 0.13.19

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 +10 -5
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -69,7 +69,7 @@ Every variable the server reads (all optional):
69
69
  | `AGENT402_MAX_PER_CALL` | `4` | Refuse any single call priced above this many USD (e.g. `0.05`); `off` disables it. Applies to the wallet and the credits path. |
70
70
  | `AGENT402_BUDGET` | no session cap | Opt-in hard cap on total USD spent per session (e.g. `1.00`); unset or `off` means no session cap. Applies to the wallet and the credits path. |
71
71
  | `AGENT402_NETWORKS` | _(unset)_ | Restrict + order the chains to pay on - e.g. `robinhood` (USDG on Robinhood Chain), `base,solana`, or a raw CAIP-2 like `eip155:4663`. Unset = the client picks (effectively Base on multi-chain sellers). |
72
- | `AGENT402_ASYNC` | `auto` | Slow routes (reports, video, the premium image; `async.recommended` on their `/api/pricing` row) are paid with `Prefer: respond-async` and collected from their job link, so a long run never outlives the connection. `off` waits on the connection instead; `always` uses a job on every route that runs as one. |
72
+ | `AGENT402_ASYNC` | `auto` | Slow routes (reports, video, the premium image; `async.recommended` on their `/api/pricing` row) are paid with `Prefer: respond-async` and collected from their job link, so a long run never outlives the connection. `off` waits on the connection instead (since 0.13.18 sending `Prefer: wait=<maxSeconds>` where the row gives `async.preferWait`); `always` uses a job on every route that runs as one. |
73
73
  | `AGENT402_ASYNC_TIMEOUT_MS` | `900000` | How long to poll a job before answering with its link (`structuredContent.jobUrl`) to collect later. |
74
74
 
75
75
  The per-call cap is on by default and the session budget is opt-in; both are
package/index.js CHANGED
@@ -295,8 +295,10 @@ function acceptsOf(obj) {
295
295
  * leaves the body `{}`; v1 sellers put it in the body. Header first.
296
296
  *
297
297
  * Each accept is priced from the known-asset table (./known-assets.js), never
298
- * from a decimals value the seller sends. The credits gate debits its own
299
- * quote, so the dearest known accept is the price. */
298
+ * from a decimals value the seller sends. The credits gate debits the route's
299
+ * own quote, and no accept is below it (a chain premium or price floor only
300
+ * raises an accept), so the cheapest known accept is the price: counting the
301
+ * dearest would charge the budget for another chain's floor. */
300
302
  async function quotedUsd(url, init, listUsd) {
301
303
  if (!CAPS_CONFIGURED) return { usd: listUsd };
302
304
  let q = null;
@@ -312,9 +314,9 @@ async function quotedUsd(url, init, listUsd) {
312
314
  q = quoteOf(acceptsOf(body));
313
315
  }
314
316
  } catch { return { usd: listUsd }; /* no readable 402: the advertised price */ }
315
- if (!q || q.max == null) return { usd: listUsd };
317
+ if (!q || q.min == null) return { usd: listUsd };
316
318
  // Larger of the two: an understated catalog must not lower the ceiling.
317
- return { usd: Math.max(listUsd, q.max) };
319
+ return { usd: Math.max(listUsd, q.min) };
318
320
  }
319
321
 
320
322
  // A refused call's tool text. A 402 body from an x402 v2 seller may also carry
@@ -358,7 +360,10 @@ async function callEndpoint(tool, args = {}, { onProgress = null } = {}) {
358
360
  const init = { method: tool.method, headers: { Accept: "application/json" } };
359
361
  // A slow route runs as a job (./async-job.js): the paid call asks for one,
360
362
  // and the job link is polled (free) until the answer is ready.
361
- const asyncHeaders = shouldRequestAsync(tool.async, ASYNC_MODE) ? { Prefer: "respond-async" } : {};
363
+ // With async off, a route that needs a header either way says how long to
364
+ // wait (async.preferWait), so the call waits on the connection instead.
365
+ const asyncHeaders = shouldRequestAsync(tool.async, ASYNC_MODE) ? { Prefer: "respond-async" }
366
+ : typeof tool.async?.preferWait === "string" && /^wait=\d+$/.test(tool.async.preferWait) ? { Prefer: tool.async.preferWait } : {};
362
367
  const collect = (r) => awaitJob(r, { baseUrl: BASE, fetchImpl: ownFetch, timeoutMs: ASYNC_TIMEOUT_MS, onProgress, slug: tool.slug });
363
368
  if (tool.method === "GET") {
364
369
  for (const [k, v] of Object.entries(args)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent402-mcp",
3
- "version": "0.13.17",
3
+ "version": "0.13.19",
4
4
  "mcpName": "io.github.MikeyPetrillo/agent402",
5
5
  "author": "Havok Holdings LLC <mike@agent402.tools> (https://agent402.tools)",
6
6
  "homepage": "https://agent402.tools",
@@ -88,7 +88,7 @@
88
88
  "fast-uri": "3.1.8",
89
89
  "body-parser": "2.3.0",
90
90
  "@hono/node-server": "2.0.12",
91
- "ip-address": "10.7.1",
91
+ "ip-address": "10.7.4",
92
92
  "@solana-program/token": "0.17.0",
93
93
  "@solana-program/compute-budget": "0.19.0",
94
94
  "@solana-program/token-2022": "0.19.0",