@vapi-network/mcp 0.9.2 → 0.9.4

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 CHANGED
@@ -45,7 +45,7 @@ One entry point, `@vapi-network/mcp`, exporting `createVapiServer`,
45
45
  | Name | What it is | Since |
46
46
  | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- |
47
47
  | `AgentEvent` | type AgentEvent = \| { type: "step"; n: number } \| { type: "tool"; name: string; summary: string } \| { type: "paid"; ref: string; amountUsd: number; network: string } \| { type: "declined"; ref: string; reason: string } \| { type: "stopped"; reason: "finished"... | 0.5.0 or earlier |
48
- | `CallToolInput` | type CallToolInput = { id?: string; url?: string; method?: string; endpoint?: string; body?: unknown; maxPriceUsd?: number \| string; network?: string; expectedPayTo?: string; contentType?: string; } | 0.5.0 or earlier |
48
+ | `CallToolInput` | type CallToolInput = { id?: string; url?: string; method?: string; endpoint?: string; body?: unknown; maxPriceUsd?: number \| string; network?: string; expectedPayTo?: string; contentType?: string; timeoutSeconds?: number; } | 0.5.0 or earlier |
49
49
  | `CallToolResult` | type CallToolResult = { status: number; body: unknown; verification?: ListingVerification; outcome?: "signed_in"; payment: null \| { network: string; amountAtomic: string; amountUsd: string; asset: string; payTo: string; settlement: unknown \| null; proof: st... | 0.5.0 or earlier |
50
50
  | `CallReadInput` | type CallReadInput = { url: string } | 0.8.0 |
51
51
  | `CallReadOutput` | type CallReadOutput = { status: number; contentType: string \| null; body: unknown } | 0.8.0 |
@@ -80,13 +80,35 @@ export declare const inspectToolResultSchema: z.ZodObject<{
80
80
  count: z.ZodNumber;
81
81
  }, z.core.$loose>>>;
82
82
  }, z.core.$loose>>;
83
- payment: z.ZodNullable<z.ZodObject<{
83
+ payment: z.ZodNullable<z.ZodUnion<readonly [z.ZodObject<{
84
84
  scheme: z.ZodLiteral<"exact">;
85
85
  network: z.ZodString;
86
86
  asset: z.ZodString;
87
87
  payTo: z.ZodString;
88
- checkedAt: z.ZodString;
89
- }, z.core.$strip>>;
88
+ checkedAt: z.ZodISODateTime;
89
+ }, z.core.$loose>, z.ZodObject<{
90
+ scheme: z.ZodLiteral<"exact">;
91
+ network: z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d">]>;
92
+ asset: z.ZodString;
93
+ payTo: z.ZodString;
94
+ checkedAt: z.ZodISODateTime;
95
+ }, z.core.$loose>, z.ZodObject<{
96
+ protocol: z.ZodLiteral<"mpp">;
97
+ intent: z.ZodNullable<z.ZodEnum<{
98
+ charge: "charge";
99
+ authorize: "authorize";
100
+ subscription: "subscription";
101
+ }>>;
102
+ method: z.ZodNullable<z.ZodString>;
103
+ checkedAt: z.ZodISODateTime;
104
+ network: z.ZodOptional<z.ZodNever>;
105
+ payTo: z.ZodOptional<z.ZodNever>;
106
+ }, z.core.$loose>, z.ZodObject<{
107
+ protocol: z.ZodString;
108
+ checkedAt: z.ZodISODateTime;
109
+ network: z.ZodOptional<z.ZodNever>;
110
+ payTo: z.ZodOptional<z.ZodNever>;
111
+ }, z.core.$loose>]>>;
90
112
  }, z.core.$strip>;
91
113
  export declare const callSearchInputSchema: z.ZodObject<{
92
114
  query: z.ZodOptional<z.ZodString>;
@@ -114,6 +136,7 @@ export declare const callPayInputSchema: z.ZodObject<{
114
136
  network: z.ZodOptional<z.ZodString>;
115
137
  expectedPayTo: z.ZodOptional<z.ZodString>;
116
138
  maxPriceUsd: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
139
+ timeoutSeconds: z.ZodOptional<z.ZodNumber>;
117
140
  wallet: z.ZodOptional<z.ZodString>;
118
141
  }, z.core.$strip>;
119
142
  export declare const callSearch: import("./define.js").Action<{
@@ -150,7 +173,7 @@ export declare const callSearch: import("./define.js").Action<{
150
173
  summary: string;
151
174
  badges: {
152
175
  [x: string]: unknown;
153
- code: "partner" | "live_x402" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor";
176
+ code: "partner" | "live_x402" | "mpp" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor" | "unverified";
154
177
  label: string;
155
178
  }[];
156
179
  facts: {
@@ -214,7 +237,7 @@ export declare const callSearch: import("./define.js").Action<{
214
237
  summary: string;
215
238
  badges: {
216
239
  [x: string]: unknown;
217
- code: "partner" | "live_x402" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor";
240
+ code: "partner" | "live_x402" | "mpp" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor" | "unverified";
218
241
  label: string;
219
242
  }[];
220
243
  facts: {
@@ -270,7 +293,7 @@ export declare const callSearch: import("./define.js").Action<{
270
293
  summary: string;
271
294
  badges: {
272
295
  [x: string]: unknown;
273
- code: "partner" | "live_x402" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor";
296
+ code: "partner" | "live_x402" | "mpp" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor" | "unverified";
274
297
  label: string;
275
298
  }[];
276
299
  facts: {
@@ -326,7 +349,7 @@ export declare const callSearch: import("./define.js").Action<{
326
349
  summary: string;
327
350
  badges: {
328
351
  [x: string]: unknown;
329
- code: "partner" | "live_x402" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor";
352
+ code: "partner" | "live_x402" | "mpp" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor" | "unverified";
330
353
  label: string;
331
354
  }[];
332
355
  facts: {
@@ -379,11 +402,33 @@ export declare const callInspect: import("./define.js").Action<{
379
402
  description: string;
380
403
  verification: "none" | "requested" | "verified";
381
404
  payment: {
405
+ [x: string]: unknown;
382
406
  scheme: "exact";
383
407
  network: string;
384
408
  asset: string;
385
409
  payTo: string;
386
410
  checkedAt: string;
411
+ } | {
412
+ [x: string]: unknown;
413
+ scheme: "exact";
414
+ network: string;
415
+ asset: string;
416
+ payTo: string;
417
+ checkedAt: string;
418
+ } | {
419
+ [x: string]: unknown;
420
+ protocol: "mpp";
421
+ intent: "charge" | "authorize" | "subscription" | null;
422
+ method: string | null;
423
+ checkedAt: string;
424
+ network?: undefined;
425
+ payTo?: undefined;
426
+ } | {
427
+ [x: string]: unknown;
428
+ protocol: string;
429
+ checkedAt: string;
430
+ network?: undefined;
431
+ payTo?: undefined;
387
432
  } | null;
388
433
  operationId?: string | undefined;
389
434
  requestContentType?: string | undefined;
@@ -430,6 +475,7 @@ export declare const callPay: import("./define.js").Action<{
430
475
  network?: string | undefined;
431
476
  expectedPayTo?: string | undefined;
432
477
  maxPriceUsd?: string | number | undefined;
478
+ timeoutSeconds?: number | undefined;
433
479
  wallet?: string | undefined;
434
480
  }, {
435
481
  wallet: string;
@@ -41,7 +41,7 @@ export declare const actions: readonly [Action<{
41
41
  summary: string;
42
42
  badges: {
43
43
  [x: string]: unknown;
44
- code: "partner" | "live_x402" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor";
44
+ code: "partner" | "live_x402" | "mpp" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor" | "unverified";
45
45
  label: string;
46
46
  }[];
47
47
  facts: {
@@ -105,7 +105,7 @@ export declare const actions: readonly [Action<{
105
105
  summary: string;
106
106
  badges: {
107
107
  [x: string]: unknown;
108
- code: "partner" | "live_x402" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor";
108
+ code: "partner" | "live_x402" | "mpp" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor" | "unverified";
109
109
  label: string;
110
110
  }[];
111
111
  facts: {
@@ -161,7 +161,7 @@ export declare const actions: readonly [Action<{
161
161
  summary: string;
162
162
  badges: {
163
163
  [x: string]: unknown;
164
- code: "partner" | "live_x402" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor";
164
+ code: "partner" | "live_x402" | "mpp" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor" | "unverified";
165
165
  label: string;
166
166
  }[];
167
167
  facts: {
@@ -217,7 +217,7 @@ export declare const actions: readonly [Action<{
217
217
  summary: string;
218
218
  badges: {
219
219
  [x: string]: unknown;
220
- code: "partner" | "live_x402" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor";
220
+ code: "partner" | "live_x402" | "mpp" | "payout_wallet_confirmed" | "vapi_verified" | "external_catalog" | "approved_vendor" | "unverified";
221
221
  label: string;
222
222
  }[];
223
223
  facts: {
@@ -269,11 +269,33 @@ export declare const actions: readonly [Action<{
269
269
  description: string;
270
270
  verification: "none" | "requested" | "verified";
271
271
  payment: {
272
+ [x: string]: unknown;
273
+ scheme: "exact";
274
+ network: string;
275
+ asset: string;
276
+ payTo: string;
277
+ checkedAt: string;
278
+ } | {
279
+ [x: string]: unknown;
272
280
  scheme: "exact";
273
281
  network: string;
274
282
  asset: string;
275
283
  payTo: string;
276
284
  checkedAt: string;
285
+ } | {
286
+ [x: string]: unknown;
287
+ protocol: "mpp";
288
+ intent: "charge" | "authorize" | "subscription" | null;
289
+ method: string | null;
290
+ checkedAt: string;
291
+ network?: undefined;
292
+ payTo?: undefined;
293
+ } | {
294
+ [x: string]: unknown;
295
+ protocol: string;
296
+ checkedAt: string;
297
+ network?: undefined;
298
+ payTo?: undefined;
277
299
  } | null;
278
300
  operationId?: string | undefined;
279
301
  requestContentType?: string | undefined;
@@ -319,6 +341,7 @@ export declare const actions: readonly [Action<{
319
341
  network?: string | undefined;
320
342
  expectedPayTo?: string | undefined;
321
343
  maxPriceUsd?: string | number | undefined;
344
+ timeoutSeconds?: number | undefined;
322
345
  wallet?: string | undefined;
323
346
  }, {
324
347
  wallet: string;
package/dist/index.js CHANGED
@@ -38033,8 +38033,10 @@ var listingIdentitySchema = external_exports.looseObject({
38033
38033
  }).optional().catch(void 0)
38034
38034
  });
38035
38035
  var listingDisclosureShape = {
38036
- group: listingGroupSchema.optional(),
38037
- fee: listingFeeSchema.optional(),
38036
+ // Presentation metadata must not make an otherwise executable row vanish
38037
+ // when the registry adds a new group or changes the fee display shape.
38038
+ group: listingGroupSchema.optional().catch(void 0),
38039
+ fee: listingFeeSchema.optional().catch(void 0),
38038
38040
  verification: listingVerificationFieldSchema,
38039
38041
  liveness: listingLivenessSchema.optional().catch(void 0),
38040
38042
  conformance: listingConformanceSchema.optional().catch(void 0),
@@ -38042,11 +38044,13 @@ var listingDisclosureShape = {
38042
38044
  };
38043
38045
  var marketplaceBadgeCodeSchema = external_exports.enum([
38044
38046
  "live_x402",
38047
+ "mpp",
38045
38048
  "partner",
38046
38049
  "payout_wallet_confirmed",
38047
38050
  "vapi_verified",
38048
38051
  "external_catalog",
38049
- "approved_vendor"
38052
+ "approved_vendor",
38053
+ "unverified"
38050
38054
  ]);
38051
38055
  var marketplaceBadgeSchema = external_exports.looseObject({
38052
38056
  code: marketplaceBadgeCodeSchema,
@@ -38065,7 +38069,13 @@ var marketplaceCardSchema = external_exports.looseObject({
38065
38069
  summary: external_exports.string().trim().min(1).max(1e3),
38066
38070
  byline: external_exports.string().trim().min(1).max(160).optional(),
38067
38071
  bylineHref: marketplaceHrefSchema.optional(),
38068
- badges: external_exports.array(marketplaceBadgeSchema).max(8),
38072
+ badges: external_exports.preprocess(
38073
+ (badges) => Array.isArray(badges) ? badges.flatMap((badge) => {
38074
+ const parsed = marketplaceBadgeSchema.safeParse(badge);
38075
+ return parsed.success ? [parsed.data] : [];
38076
+ }) : badges,
38077
+ external_exports.array(marketplaceBadgeSchema).max(8)
38078
+ ),
38069
38079
  facts: external_exports.array(marketplacePublicFactSchema).max(12)
38070
38080
  });
38071
38081
  var marketplaceHitBase = {
@@ -44221,9 +44231,9 @@ function isRecord2(value) {
44221
44231
  var CALLABLE_CATEGORIES = ["ai", "data", "crypto", "compute", "search"];
44222
44232
  var callableCategorySchema = external_exports.enum(CALLABLE_CATEGORIES);
44223
44233
  var DISCOVERY_CATEGORIES = [...CALLABLE_CATEGORIES, "other"];
44224
- var discoveryCategorySchema = external_exports.enum(DISCOVERY_CATEGORIES);
44234
+ var discoveryCategorySchema = external_exports.string().trim().min(1);
44225
44235
  var CALLABLE_CATEGORY_SET = new Set(CALLABLE_CATEGORIES);
44226
- var serviceTierSchema = external_exports.enum(["listed", "verified", "partner"]);
44236
+ var serviceTierSchema = external_exports.string().trim().min(1);
44227
44237
  var discoveryEndpointSchema = external_exports.looseObject({
44228
44238
  name: external_exports.string(),
44229
44239
  method: external_exports.string(),
@@ -44253,6 +44263,24 @@ var discoveryEndpointSchema = external_exports.looseObject({
44253
44263
  asset: external_exports.string().refine(isSolanaAddress, "Expected a Solana base58 address."),
44254
44264
  payTo: external_exports.string().refine(isSolanaAddress, "Expected a Solana base58 address."),
44255
44265
  checkedAt: external_exports.iso.datetime()
44266
+ }),
44267
+ external_exports.looseObject({
44268
+ protocol: external_exports.literal("mpp"),
44269
+ intent: external_exports.enum(["charge", "authorize", "subscription"]).nullable(),
44270
+ method: external_exports.string().trim().min(1).max(40).nullable(),
44271
+ checkedAt: external_exports.iso.datetime(),
44272
+ // Keep common x402 properties readable on the union while making it
44273
+ // impossible for MPP metadata to masquerade as executable x402 terms.
44274
+ network: external_exports.never().optional(),
44275
+ payTo: external_exports.never().optional()
44276
+ }),
44277
+ external_exports.looseObject({
44278
+ // Future payment protocols remain visible to callers so the payment
44279
+ // layer can refuse them explicitly instead of discovery losing the row.
44280
+ protocol: external_exports.string().trim().min(1).max(40),
44281
+ checkedAt: external_exports.iso.datetime(),
44282
+ network: external_exports.never().optional(),
44283
+ payTo: external_exports.never().optional()
44256
44284
  })
44257
44285
  ]).optional()
44258
44286
  });
@@ -44346,7 +44374,7 @@ function resolveTarget(service, endpointName) {
44346
44374
  }
44347
44375
  if (targets.size !== 1) {
44348
44376
  const paymentNetworks = service.endpoints.flatMap(
44349
- (endpoint) => endpoint.payment ? [endpoint.payment.network] : []
44377
+ (endpoint) => typeof endpoint.payment?.network === "string" ? [endpoint.payment.network] : []
44350
44378
  );
44351
44379
  throw new DiscoveryCatalogError(
44352
44380
  "ambiguous_default",
@@ -45187,7 +45215,8 @@ function getVapiPaths(directory = process.env.VAPI_HOME?.trim() || join2(homedir
45187
45215
  keystore: join2(directory, "keystore.json"),
45188
45216
  receipts: join2(directory, "receipts.jsonl"),
45189
45217
  searches: join2(directory, "searches.jsonl"),
45190
- ledger: join2(directory, "spend-ledger.json")
45218
+ ledger: join2(directory, "spend-ledger.json"),
45219
+ updateCheck: join2(directory, "update-check.json")
45191
45220
  };
45192
45221
  }
45193
45222
  var getAgentCashPaths = getVapiPaths;
@@ -73038,7 +73067,7 @@ function createRunBudget(args) {
73038
73067
  import { mkdir as mkdir13, writeFile as writeFile7 } from "node:fs/promises";
73039
73068
  import { arch, platform, release } from "node:os";
73040
73069
  import { join as join11 } from "node:path";
73041
- var VAPI_CLIENT_VERSION = "0.9.2";
73070
+ var VAPI_CLIENT_VERSION = "0.9.4";
73042
73071
  async function createSupportReport(options) {
73043
73072
  const message = options.message.trim();
73044
73073
  if (!message) throw new Error("Support report message must not be empty.");
@@ -73311,7 +73340,7 @@ async function completeX402Payment(args) {
73311
73340
  let paidAttempt;
73312
73341
  const requestStarted = nowMs();
73313
73342
  try {
73314
- paidAttempt = await args.send(paidRequest);
73343
+ paidAttempt = await args.send(paidRequest, quote);
73315
73344
  } catch (error61) {
73316
73345
  if (trace) trace.phases.requestMs = elapsed(nowMs, requestStarted);
73317
73346
  throw settlementUnknown(
@@ -73329,7 +73358,7 @@ async function completeX402Payment(args) {
73329
73358
  const settleStarted = nowMs();
73330
73359
  const settlement = parseSettlementResponse(paidResponse.headers);
73331
73360
  const settlementOutcome = classifySettlement(settlement);
73332
- const receiptSettlement = sanitizeReceiptValue(settlement, receiptSecrets);
73361
+ const receiptSettlement = sanitizeReturnedValue(settlement, receiptSecrets);
73333
73362
  if (trace) {
73334
73363
  const transaction2 = settlementTransaction(receiptSettlement);
73335
73364
  const explorerUrl = transaction2 ? explorerTransactionUrl(quote.accepted.network, transaction2) : void 0;
@@ -73406,6 +73435,7 @@ async function completeX402Payment(args) {
73406
73435
  trace.phases.requestMs = (trace.phases.requestMs ?? 0) + elapsed(nowMs, bodyStarted);
73407
73436
  }
73408
73437
  }
73438
+ body = sanitizeReturnedValue(body, receiptSecrets);
73409
73439
  }
73410
73440
  const result = {
73411
73441
  response: paidResponse,
@@ -73414,7 +73444,11 @@ async function completeX402Payment(args) {
73414
73444
  quote,
73415
73445
  payer,
73416
73446
  ...payment.paymentId ? { paymentId: payment.paymentId } : {},
73417
- settlement,
73447
+ paymentProof: sanitizeReturnedValue(
73448
+ paidResponse.headers.get("x-vapi-payment-proof"),
73449
+ receiptSecrets
73450
+ ),
73451
+ settlement: receiptSettlement,
73418
73452
  settlementOutcome
73419
73453
  };
73420
73454
  if (settlementOutcome === "succeeded" && args.ceilingSweep) {
@@ -73551,19 +73585,70 @@ function sanitizeThrownError(error61, secrets) {
73551
73585
  }
73552
73586
  return new Error(message, cause === void 0 ? void 0 : { cause });
73553
73587
  }
73554
- function sanitizeReceiptValue(value, secrets, depth = 0) {
73588
+ function sanitizeReturnedValue(value, secrets) {
73555
73589
  if (typeof value === "string") return redactKnownSecrets(value, secrets);
73556
- if (value === null || typeof value !== "object") return value;
73557
- if (depth >= 16) return "[redacted nested settlement value]";
73558
- if (Array.isArray(value)) {
73559
- return value.map((item) => sanitizeReceiptValue(item, secrets, depth + 1));
73590
+ if (!isPlainReturnedContainer(value)) return value;
73591
+ const nodes = /* @__PURE__ */ new WeakMap();
73592
+ const ordered = [];
73593
+ const nodeFor = (source) => {
73594
+ const existing = nodes.get(source);
73595
+ if (existing) return existing;
73596
+ const copy = Array.isArray(source) ? new Array(source.length) : Object.create(Object.getPrototypeOf(source));
73597
+ const node2 = { source, copy, parents: /* @__PURE__ */ new Set(), changed: false };
73598
+ nodes.set(source, node2);
73599
+ ordered.push(node2);
73600
+ return node2;
73601
+ };
73602
+ const root = nodeFor(value);
73603
+ for (let index2 = 0; index2 < ordered.length; index2 += 1) {
73604
+ const node2 = ordered[index2];
73605
+ for (const [key2, item] of Object.entries(node2.source)) {
73606
+ const safeKey = Array.isArray(node2.source) ? key2 : redactKnownSecrets(key2, secrets);
73607
+ if (safeKey !== key2) node2.changed = true;
73608
+ if (typeof item === "string") {
73609
+ const safeItem = redactKnownSecrets(item, secrets);
73610
+ defineReturnedProperty(node2.copy, safeKey, safeItem);
73611
+ if (safeItem !== item) node2.changed = true;
73612
+ } else if (isPlainReturnedContainer(item)) {
73613
+ const child = nodeFor(item);
73614
+ child.parents.add(node2);
73615
+ defineReturnedProperty(node2.copy, safeKey, child.copy);
73616
+ } else {
73617
+ defineReturnedProperty(node2.copy, safeKey, item);
73618
+ }
73619
+ }
73560
73620
  }
73561
- return Object.fromEntries(
73562
- Object.entries(value).map(([key2, item]) => [
73563
- redactKnownSecrets(key2, secrets),
73564
- sanitizeReceiptValue(item, secrets, depth + 1)
73565
- ])
73566
- );
73621
+ const changed = ordered.filter((node2) => node2.changed);
73622
+ for (let index2 = 0; index2 < changed.length; index2 += 1) {
73623
+ for (const parent of changed[index2].parents) {
73624
+ if (parent.changed) continue;
73625
+ parent.changed = true;
73626
+ changed.push(parent);
73627
+ }
73628
+ }
73629
+ for (const node2 of ordered) {
73630
+ for (const [key2, item] of Object.entries(node2.source)) {
73631
+ if (!isPlainReturnedContainer(item)) continue;
73632
+ const safeKey = Array.isArray(node2.source) ? key2 : redactKnownSecrets(key2, secrets);
73633
+ const child = nodes.get(item);
73634
+ defineReturnedProperty(node2.copy, safeKey, child.changed ? child.copy : item);
73635
+ }
73636
+ }
73637
+ return root.changed ? root.copy : value;
73638
+ }
73639
+ function defineReturnedProperty(target, key2, value) {
73640
+ Object.defineProperty(target, key2, {
73641
+ value,
73642
+ enumerable: true,
73643
+ configurable: true,
73644
+ writable: true
73645
+ });
73646
+ }
73647
+ function isPlainReturnedContainer(value) {
73648
+ if (Array.isArray(value)) return true;
73649
+ if (value === null || typeof value !== "object") return false;
73650
+ const prototype = Object.getPrototypeOf(value);
73651
+ return prototype === Object.prototype || prototype === null;
73567
73652
  }
73568
73653
  function redactKnownSecrets(value, secrets) {
73569
73654
  let redacted = value;
@@ -73598,9 +73683,7 @@ function possibleSettlement(quote, payment, payer, receipt) {
73598
73683
  payTo: quote.accepted.payTo,
73599
73684
  payer,
73600
73685
  ...payment.paymentId ? { paymentId: payment.paymentId } : {},
73601
- ...isSvmPaymentRequirements(quote.accepted) ? {
73602
- authorizationTransaction: "transaction" in payment.payload.payload ? payment.payload.payload.transaction : ""
73603
- } : "authorization" in payment.payload.payload ? {
73686
+ ...isSvmPaymentRequirements(quote.accepted) ? {} : "authorization" in payment.payload.payload ? {
73604
73687
  authorizationNonce: payment.payload.payload.authorization.nonce,
73605
73688
  authorizationExpiresAt: payment.payload.payload.authorization.validBefore
73606
73689
  } : {},
@@ -73978,13 +74061,22 @@ async function sendRouterChat(deps, routerBaseUrl, routerKey, request, keyUsed)
73978
74061
  }
73979
74062
  const body = await responseText(response);
73980
74063
  if (!response.ok) {
73981
- if (response.status === 429 || body.includes("Budget has been exceeded") || body.includes("ExceededBudget")) {
74064
+ if (/budget (?:has been )?exceeded|exceededbudget/iu.test(body)) {
73982
74065
  throw new RouterClientError(
73983
74066
  "budget_exhausted",
73984
74067
  "The Router key has no remaining budget.",
73985
74068
  response.status
73986
74069
  );
73987
74070
  }
74071
+ if (response.status === 429) {
74072
+ const retryAfter = response.headers.get("retry-after")?.trim();
74073
+ const retrySeconds = retryAfter !== void 0 && /^\d+$/u.test(retryAfter) ? Number(retryAfter) : void 0;
74074
+ throw new RouterClientError(
74075
+ "rate_limited",
74076
+ `The vAPI Router is rate limited. ${retrySeconds !== void 0 && Number.isFinite(retrySeconds) ? `Retry after ${retrySeconds} seconds.` : "Wait and retry shortly."}`,
74077
+ response.status
74078
+ );
74079
+ }
73988
74080
  if (response.status === 401) {
73989
74081
  throw new RouterClientError(
73990
74082
  "no_router_key",
@@ -82382,12 +82474,13 @@ var BODY_HEADER_NAMES = [
82382
82474
  "content-type"
82383
82475
  ];
82384
82476
  async function callService(args) {
82477
+ validateTimeoutSeconds(args.input.timeoutSeconds);
82385
82478
  const trace = createCallTrace(args);
82386
82479
  let execution;
82387
82480
  try {
82388
82481
  execution = await executeCallService(args, trace);
82389
82482
  } catch (error61) {
82390
- if (!(error61 instanceof VapiCallError && error61.code === "unsupported_network")) {
82483
+ if (!(error61 instanceof VapiCallError && (error61.code === "unsupported_network" || error61.code === "unsupported_payment"))) {
82391
82484
  await recordCallError(args, error61, trace).catch(() => void 0);
82392
82485
  }
82393
82486
  throw error61;
@@ -82501,6 +82594,8 @@ async function executeCallService(args, trace) {
82501
82594
  body: method === "GET" || method === "HEAD" ? void 0 : requestBody
82502
82595
  });
82503
82596
  const request = createRequest(headers);
82597
+ const probeTimeoutMs = input2.timeoutSeconds === void 0 ? args.timeoutMs ?? 3e4 : Math.min(input2.timeoutSeconds, 30) * 1e3;
82598
+ let requestTimeoutMs = probeTimeoutMs;
82504
82599
  const fetchWithGuardedRedirects = async (candidateRequest, followRedirects = true) => {
82505
82600
  let currentRequest = candidateRequest;
82506
82601
  let followedRedirects = 0;
@@ -82508,7 +82603,7 @@ async function executeCallService(args, trace) {
82508
82603
  const attempt = await fetchAttempt(
82509
82604
  fetchImpl,
82510
82605
  new Request(currentRequest.clone(), { redirect: "manual" }),
82511
- args.timeoutMs ?? 3e4
82606
+ requestTimeoutMs
82512
82607
  );
82513
82608
  const response = attempt.response;
82514
82609
  if (!isRedirectStatus2(response.status)) {
@@ -82663,7 +82758,12 @@ async function executeCallService(args, trace) {
82663
82758
  account,
82664
82759
  caps: args.spendCaps ?? config2.spendCaps,
82665
82760
  config: payableConfig(config2, account),
82666
- send: async (paidRequest) => {
82761
+ send: async (paidRequest, quote) => {
82762
+ requestTimeoutMs = paidRequestTimeoutMs(
82763
+ input2.timeoutSeconds,
82764
+ args.timeoutMs,
82765
+ quote.accepted.maxTimeoutSeconds
82766
+ );
82667
82767
  paidAttempt = await fetchWithGuardedRedirects(paidRequest, false);
82668
82768
  return paidAttempt;
82669
82769
  },
@@ -82702,7 +82802,7 @@ async function executeCallService(args, trace) {
82702
82802
  asset: completed.quote.accepted.asset,
82703
82803
  payTo: completed.quote.accepted.payTo,
82704
82804
  settlement: settlementWithExplorer2(completed.settlement, completed.quote.accepted.network),
82705
- proof: completed.response.headers.get("x-vapi-payment-proof")
82805
+ proof: completed.paymentProof
82706
82806
  },
82707
82807
  ...verificationFor(endpoint),
82708
82808
  ...expectedRequestFor(endpoint, completed.response.status)
@@ -82949,8 +83049,16 @@ async function resolveCallEndpoint(id2, endpointName, marketplaceHit, config2, f
82949
83049
  );
82950
83050
  }
82951
83051
  function registeredEndpoint(listing, verification) {
83052
+ const { payment, ...endpoint } = listing.endpoint;
83053
+ if (payment && (typeof payment.protocol === "string" || typeof payment.network !== "string")) {
83054
+ throw new VapiCallError(
83055
+ "unsupported_payment",
83056
+ `Payment protocol ${payment.protocol} is not supported. This client pays x402 exact USDC endpoints only.`
83057
+ );
83058
+ }
82952
83059
  return {
82953
- ...listing.endpoint,
83060
+ ...endpoint,
83061
+ ...payment ? { payment: { network: payment.network, payTo: payment.payTo } } : {},
82954
83062
  verification: verification ?? listing.service.verification,
82955
83063
  serviceNetworks: listing.service.networks,
82956
83064
  registered: true,
@@ -83112,7 +83220,7 @@ async function readResponseBody2(response) {
83112
83220
  async function fetchAttempt(fetchImpl, request, timeoutMs) {
83113
83221
  const controller = new AbortController();
83114
83222
  let rejectTimeout = null;
83115
- const timeoutError = new Error(`API request timed out after ${timeoutMs}ms.`);
83223
+ const timeoutError = new Error(`API request timed out after ${timeoutMs / 1e3} seconds.`);
83116
83224
  const timedOut = new Promise((_resolve, reject) => {
83117
83225
  rejectTimeout = reject;
83118
83226
  });
@@ -83152,6 +83260,19 @@ async function fetchAttempt(fetchImpl, request, timeoutMs) {
83152
83260
  throw error61;
83153
83261
  }
83154
83262
  }
83263
+ function validateTimeoutSeconds(timeoutSeconds) {
83264
+ if (timeoutSeconds !== void 0 && (!Number.isInteger(timeoutSeconds) || timeoutSeconds < 1 || timeoutSeconds > 300)) {
83265
+ throw new Error("call timeoutSeconds must be an integer from 1 to 300 seconds.");
83266
+ }
83267
+ }
83268
+ function paidRequestTimeoutMs(timeoutSeconds, internalTimeoutMs, offerTimeoutSeconds) {
83269
+ const usableOfferTimeout = Number.isInteger(offerTimeoutSeconds) && offerTimeoutSeconds > 0 ? offerTimeoutSeconds : void 0;
83270
+ if (timeoutSeconds !== void 0) {
83271
+ return Math.min(timeoutSeconds, usableOfferTimeout ?? timeoutSeconds) * 1e3;
83272
+ }
83273
+ if (internalTimeoutMs !== void 0) return internalTimeoutMs;
83274
+ return usableOfferTimeout === void 0 ? 12e4 : Math.min(12e4, Math.max(3e4, usableOfferTimeout * 1e3));
83275
+ }
83155
83276
  function mapX402PaymentError(error61, resumeId) {
83156
83277
  if (!(error61 instanceof X402PaymentError)) return error61;
83157
83278
  if (error61.code === "payment_rejected") {
@@ -83167,9 +83288,10 @@ function mapX402PaymentError(error61, resumeId) {
83167
83288
  });
83168
83289
  }
83169
83290
  const resume = resumeId !== void 0 && error61.possibleSettlement?.authorizationNonce ? ` Check whether it settled with \`vapi pay --resume ${resumeId}\` before paying again.` : "";
83291
+ const timeoutDetail = error61.cause instanceof Error && error61.cause.message.startsWith("API request timed out after ") ? `${error61.cause.message} ` : "";
83170
83292
  return new VapiCallError(
83171
83293
  "settlement_unknown",
83172
- `${error61.message}${resume}`,
83294
+ `${timeoutDetail}${error61.message}${resume}`,
83173
83295
  error61.possibleSettlement,
83174
83296
  { cause: error61.cause }
83175
83297
  );
@@ -83301,13 +83423,7 @@ var inspectToolResultSchema = external_exports.object({
83301
83423
  liveness: listingLivenessSchema.optional(),
83302
83424
  conformance: listingConformanceSchema.optional(),
83303
83425
  identity: listingIdentitySchema.optional(),
83304
- payment: external_exports.object({
83305
- scheme: external_exports.literal("exact"),
83306
- network: external_exports.string(),
83307
- asset: external_exports.string(),
83308
- payTo: external_exports.string(),
83309
- checkedAt: external_exports.string()
83310
- }).nullable()
83426
+ payment: discoveryEndpointSchema.shape.payment.unwrap().nullable()
83311
83427
  });
83312
83428
  var callSearchInputSchema = external_exports.object({
83313
83429
  query: external_exports.string().trim().max(200).optional().describe("Capability, API, service, or request."),
@@ -83336,7 +83452,10 @@ var callPayInputSchema = external_exports.object({
83336
83452
  (value) => /^0x[0-9a-fA-F]{40}$/.test(value) || isSolanaAddress(value),
83337
83453
  "Expected an EVM or Solana address."
83338
83454
  ).optional(),
83339
- maxPriceUsd: external_exports.union([external_exports.number().nonnegative(), external_exports.string().regex(/^\d+(?:\.\d{1,6})?$/)]).optional()
83455
+ maxPriceUsd: external_exports.union([external_exports.number().nonnegative(), external_exports.string().regex(/^\d+(?:\.\d{1,6})?$/)]).optional(),
83456
+ timeoutSeconds: external_exports.number().int().min(1).max(300).optional().describe(
83457
+ "Seconds to wait for the paid response. Default: the provider's maxTimeoutSeconds, at most 120."
83458
+ )
83340
83459
  });
83341
83460
  var callSearch = defineAction({
83342
83461
  name: "call.search",
@@ -83599,7 +83718,7 @@ async function readResult(response, signal, secrets = []) {
83599
83718
  return {
83600
83719
  status: response.status,
83601
83720
  contentType: contentType === null ? null : redactKnownSecrets2(contentType, secrets),
83602
- body: sanitizeReturnedValue(await readResponseBody3(response, contentType, signal), secrets)
83721
+ body: sanitizeReturnedValue2(await readResponseBody3(response, contentType, signal), secrets)
83603
83722
  };
83604
83723
  }
83605
83724
  async function readResponseBody3(response, contentType, signal) {
@@ -83644,17 +83763,17 @@ function isJsonContentType2(value) {
83644
83763
  const mediaType = value?.split(";", 1)[0]?.trim().toLowerCase() ?? "";
83645
83764
  return mediaType === "application/json" || mediaType.endsWith("+json");
83646
83765
  }
83647
- function sanitizeReturnedValue(value, secrets, depth = 0) {
83766
+ function sanitizeReturnedValue2(value, secrets, depth = 0) {
83648
83767
  if (typeof value === "string") return redactKnownSecrets2(value, secrets);
83649
83768
  if (value === null || typeof value !== "object") return value;
83650
83769
  if (depth >= 16) return "[redacted nested response value]";
83651
83770
  if (Array.isArray(value)) {
83652
- return value.map((item) => sanitizeReturnedValue(item, secrets, depth + 1));
83771
+ return value.map((item) => sanitizeReturnedValue2(item, secrets, depth + 1));
83653
83772
  }
83654
83773
  return Object.fromEntries(
83655
83774
  Object.entries(value).map(([key2, item]) => [
83656
83775
  redactKnownSecrets2(key2, secrets),
83657
- sanitizeReturnedValue(item, secrets, depth + 1)
83776
+ sanitizeReturnedValue2(item, secrets, depth + 1)
83658
83777
  ])
83659
83778
  );
83660
83779
  }
@@ -89166,7 +89285,13 @@ function toolError(error61) {
89166
89285
  {
89167
89286
  error: error61.message,
89168
89287
  code: error61.code,
89169
- ...error61.possibleSettlement ? { possibleSettlement: error61.possibleSettlement } : {},
89288
+ ...error61.possibleSettlement ? {
89289
+ possibleSettlement: Object.fromEntries(
89290
+ Object.entries(error61.possibleSettlement).filter(
89291
+ ([key2]) => key2 !== "authorizationTransaction"
89292
+ )
89293
+ )
89294
+ } : {},
89170
89295
  ...error61.paymentRejection ? { paymentRejection: error61.paymentRejection } : {},
89171
89296
  ...error61.confirmedSettlement ? { confirmedSettlement: error61.confirmedSettlement } : {}
89172
89297
  },