@nuanu-ai/agentify-contracts 0.3.2 → 0.4.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.
- package/README.md +1 -1
- package/dist/api.d.ts +11 -6
- package/dist/api.js +46 -12
- package/dist/index.d.ts +1 -0
- package/dist/order-status.js +16 -3
- package/dist/results.js +4 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ The contract is versioned, and the version is how an SDK and a gateway agree
|
|
|
23
23
|
that they read the same vocabulary; a worker whose version the gateway does not
|
|
24
24
|
share stops at startup rather than half understanding a document. What the
|
|
25
25
|
merchant-facing side of all this looks like in use is at
|
|
26
|
-
<https://
|
|
26
|
+
<https://agentify.ad/docs/>.
|
|
27
27
|
|
|
28
28
|
## License
|
|
29
29
|
|
package/dist/api.d.ts
CHANGED
|
@@ -225,9 +225,11 @@ export declare const ReceiptListSchema: z.ZodObject<{
|
|
|
225
225
|
/**
|
|
226
226
|
* The question a merchant puts in the query string when listing orders.
|
|
227
227
|
*
|
|
228
|
-
* `open=true` narrows the list to the orders
|
|
229
|
-
*
|
|
230
|
-
*
|
|
228
|
+
* `open=true` narrows the list to the orders a restarted worker should walk:
|
|
229
|
+
* ones the merchant was handed and has not finished, and the two that stay
|
|
230
|
+
* open after the purchase itself is over, an order owing a refund and one
|
|
231
|
+
* delivered but never paid for. An order that was priced and never paid, and
|
|
232
|
+
* never reached the handler, is not in that narrowing. Leaving the field out
|
|
231
233
|
* asks for everything.
|
|
232
234
|
*
|
|
233
235
|
* The value is text and not a boolean, because that is what a query string
|
|
@@ -455,9 +457,9 @@ export declare const PurchaseRequestSchema: z.ZodObject<{
|
|
|
455
457
|
/**
|
|
456
458
|
* What became of a purchase, told to the agent that made it.
|
|
457
459
|
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
460
|
+
* The shape of the list is the decision rather than its length. This document
|
|
461
|
+
* is what the buyer is owed — where their order stands, what it cost them, the
|
|
462
|
+
* goods once those exist, and where to ask again — and it is deliberately
|
|
461
463
|
* smaller than the merchant's own view of the same order. It carries no
|
|
462
464
|
* merchant, no merchant's key for the product, none of the parameters the
|
|
463
465
|
* buyer sent and nothing about any other order, because whoever holds an
|
|
@@ -490,6 +492,7 @@ export declare const PurchaseRequestSchema: z.ZodObject<{
|
|
|
490
492
|
*/
|
|
491
493
|
export declare const AgentOrderStatusSchema: z.ZodObject<{
|
|
492
494
|
order_id: z.ZodString;
|
|
495
|
+
status_url: z.ZodURL;
|
|
493
496
|
status: z.ZodEnum<{
|
|
494
497
|
delivered: "delivered";
|
|
495
498
|
in_progress: "in_progress";
|
|
@@ -1826,6 +1829,7 @@ export declare const API_ROUTES: Readonly<{
|
|
|
1826
1829
|
response: {
|
|
1827
1830
|
document: z.ZodObject<{
|
|
1828
1831
|
order_id: z.ZodString;
|
|
1832
|
+
status_url: z.ZodURL;
|
|
1829
1833
|
status: z.ZodEnum<{
|
|
1830
1834
|
delivered: "delivered";
|
|
1831
1835
|
in_progress: "in_progress";
|
|
@@ -1861,6 +1865,7 @@ export declare const API_ROUTES: Readonly<{
|
|
|
1861
1865
|
response: {
|
|
1862
1866
|
document: z.ZodObject<{
|
|
1863
1867
|
order_id: z.ZodString;
|
|
1868
|
+
status_url: z.ZodURL;
|
|
1864
1869
|
status: z.ZodEnum<{
|
|
1865
1870
|
delivered: "delivered";
|
|
1866
1871
|
in_progress: "in_progress";
|
package/dist/api.js
CHANGED
|
@@ -129,9 +129,11 @@ export const ReceiptListSchema = z
|
|
|
129
129
|
/**
|
|
130
130
|
* The question a merchant puts in the query string when listing orders.
|
|
131
131
|
*
|
|
132
|
-
* `open=true` narrows the list to the orders
|
|
133
|
-
*
|
|
134
|
-
*
|
|
132
|
+
* `open=true` narrows the list to the orders a restarted worker should walk:
|
|
133
|
+
* ones the merchant was handed and has not finished, and the two that stay
|
|
134
|
+
* open after the purchase itself is over, an order owing a refund and one
|
|
135
|
+
* delivered but never paid for. An order that was priced and never paid, and
|
|
136
|
+
* never reached the handler, is not in that narrowing. Leaving the field out
|
|
135
137
|
* asks for everything.
|
|
136
138
|
*
|
|
137
139
|
* The value is text and not a boolean, because that is what a query string
|
|
@@ -146,7 +148,7 @@ export const OrderListQuerySchema = z
|
|
|
146
148
|
open: z.enum(["true", "false"]).optional(),
|
|
147
149
|
})
|
|
148
150
|
.meta({
|
|
149
|
-
description: 'Which orders to list. Written as text because a query string carries text. "true" narrows the list to the orders
|
|
151
|
+
description: 'Which orders to list. Written as text because a query string carries text. "true" narrows the list to the orders a restarted worker should walk: ones the merchant was handed and has not finished, an order owing a refund, and one delivered but never paid for. An order that was priced and never paid, and never reached the handler, is not in that narrowing. Leaving the field out asks for everything.',
|
|
150
152
|
});
|
|
151
153
|
/**
|
|
152
154
|
* What a worker asks of one poll.
|
|
@@ -309,9 +311,9 @@ export const PurchaseRequestSchema = z
|
|
|
309
311
|
/**
|
|
310
312
|
* What became of a purchase, told to the agent that made it.
|
|
311
313
|
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
314
|
+
* The shape of the list is the decision rather than its length. This document
|
|
315
|
+
* is what the buyer is owed — where their order stands, what it cost them, the
|
|
316
|
+
* goods once those exist, and where to ask again — and it is deliberately
|
|
315
317
|
* smaller than the merchant's own view of the same order. It carries no
|
|
316
318
|
* merchant, no merchant's key for the product, none of the parameters the
|
|
317
319
|
* buyer sent and nothing about any other order, because whoever holds an
|
|
@@ -345,6 +347,38 @@ export const PurchaseRequestSchema = z
|
|
|
345
347
|
export const AgentOrderStatusSchema = z
|
|
346
348
|
.strictObject({
|
|
347
349
|
order_id: IdentifierSchema,
|
|
350
|
+
/**
|
|
351
|
+
* Where this order is read again: the whole address of its status route,
|
|
352
|
+
* scheme and host included.
|
|
353
|
+
*
|
|
354
|
+
* It exists for the agent that bought goods that come later. That agent
|
|
355
|
+
* holds this document and nothing else, it has already paid, and the
|
|
356
|
+
* goods are collected at this address. The path is not something it could
|
|
357
|
+
* work out from what it holds — the purchase was made at an address that
|
|
358
|
+
* names the product rather than the order — and a guess that misses is
|
|
359
|
+
* answered `no_such_route`, which says nothing about the order at all.
|
|
360
|
+
*
|
|
361
|
+
* Absolute, so that it is called as it stands: a bare path would have to
|
|
362
|
+
* be joined onto a host the agent was never told was the right one. It is
|
|
363
|
+
* built from the address the gateway is configured to answer as and never
|
|
364
|
+
* from the request that asked, because behind the proxy that ends an
|
|
365
|
+
* agent's TLS connection the request says plain http and names whatever
|
|
366
|
+
* host the proxy or the caller wrote. Plain http is allowed by the pattern
|
|
367
|
+
* all the same, because a gateway on a developer's own machine answers on
|
|
368
|
+
* it; a deployment's address is https because its configuration is.
|
|
369
|
+
*
|
|
370
|
+
* The scheme is a pattern rather than zod's own protocol option for the
|
|
371
|
+
* reason the price hook's is (`PriceCheckSchema` in `card.ts`): a pattern
|
|
372
|
+
* is what survives into the JSON Schema export, so a client generated from
|
|
373
|
+
* that document refuses a bare path as well. It is case-sensitive because
|
|
374
|
+
* a flag on a pattern does not survive that export, and a schema that read
|
|
375
|
+
* the scheme without regard to case would accept what the exported
|
|
376
|
+
* document refuses. Nothing is lost by it: the gateway's configuration
|
|
377
|
+
* already requires its public address in lower case.
|
|
378
|
+
*/
|
|
379
|
+
status_url: z
|
|
380
|
+
.url()
|
|
381
|
+
.regex(/^https?:\/\//, "an order's status address is a whole http or https address, not a path"),
|
|
348
382
|
status: OrderStatusSchema,
|
|
349
383
|
/**
|
|
350
384
|
* The price this order was priced at, or null where nobody ever named one
|
|
@@ -412,7 +446,7 @@ export const AgentOrderStatusSchema = z
|
|
|
412
446
|
refusal: RefusalSchema.optional(),
|
|
413
447
|
})
|
|
414
448
|
.meta({
|
|
415
|
-
description: 'What became of one purchase, in the words an agent and a merchant both read: where the order stands, what it was priced at, the goods once they are the buyer\'s, and why the merchant would not sell where that is what ended it. It is smaller than the merchant\'s own view of the same order on purpose — no merchant, no merchant\'s own key for the product, none of the purchase parameters and nothing about any other order. The price is what the buyer was asked for and not proof that anything was charged: an order that was priced and then ended without a sale still carries it, and the status is what says which happened. A null price means nobody ever named one for this order, and a null delivery means there are no goods here to hand over; both fields are always present, because an absent field is a silence a reader cannot tell from an oversight. "refusal" is the exception and is present only where a merchant refused: their own short code to branch on and their own sentence to show, carried across unchanged. The code is an open set — "out_of_stock", "invalid_params" and "cannot_fulfill" are read the same way by everybody, and a merchant whose reason fits none of them sends their own word, so an unfamiliar code has to fall through to the sentence rather than break a reader. An absent "refusal" means there is no refusal to quote and never that one was dropped, which leaves two endings still coarse: "rejected" also covers a product that was gone and a payment that failed its check, and neither of those was worded by anybody — the first because a price answer of "not available" carries no words, the second because it is refused at the door in an error envelope instead. A null delivery is likewise not a promise that no goods were ever made: a purchase whose charge failed or went unanswered can leave goods the buyer has not paid for, and this document withholds them rather than describing them. Every answer says whether the money behind the purchase was real: a gateway settling against nothing produces every other field here exactly as a real charge would, so a reader taking this for proof of a payment has to read that word first.',
|
|
449
|
+
description: 'What became of one purchase, in the words an agent and a merchant both read: where the order stands, what it was priced at, the goods once they are the buyer\'s, and why the merchant would not sell where that is what ended it. "status_url" is where this document is read again — the whole address of the order\'s status route, and the place an agent that bought goods that come later collects them. It is absolute and called as it stands, and it is the address the gateway is configured to answer as, never one taken from the request that asked. It is smaller than the merchant\'s own view of the same order on purpose — no merchant, no merchant\'s own key for the product, none of the purchase parameters and nothing about any other order. The price is what the buyer was asked for and not proof that anything was charged: an order that was priced and then ended without a sale still carries it, and the status is what says which happened. A null price means nobody ever named one for this order, and a null delivery means there are no goods here to hand over; both fields are always present, because an absent field is a silence a reader cannot tell from an oversight. "refusal" is the exception and is present only where a merchant refused: their own short code to branch on and their own sentence to show, carried across unchanged. The code is an open set — "out_of_stock", "invalid_params" and "cannot_fulfill" are read the same way by everybody, and a merchant whose reason fits none of them sends their own word, so an unfamiliar code has to fall through to the sentence rather than break a reader. An absent "refusal" means there is no refusal to quote and never that one was dropped, which leaves two endings still coarse: "rejected" also covers a product that was gone and a payment that failed its check, and neither of those was worded by anybody — the first because a price answer of "not available" carries no words, the second because it is refused at the door in an error envelope instead. A null delivery is likewise not a promise that no goods were ever made: a purchase whose charge failed or went unanswered can leave goods the buyer has not paid for, and this document withholds them rather than describing them. Every answer says whether the money behind the purchase was real: a gateway settling against nothing produces every other field here exactly as a real charge would, so a reader taking this for proof of a payment has to read that word first.',
|
|
416
450
|
});
|
|
417
451
|
/**
|
|
418
452
|
* The catalog as an agent reads it.
|
|
@@ -680,7 +714,7 @@ export const API_ROUTES = Object.freeze({
|
|
|
680
714
|
method: "POST",
|
|
681
715
|
path: "/v0/catalog/publish",
|
|
682
716
|
auth: "merchant_key",
|
|
683
|
-
description: "Publishes one product, or says what is wrong with the card. Republishing under the same merchant_item_id is how a card is changed rather than how a second one appears. The catalog identifier comes back beside ok, and from then on it is what an agent, a purchase and a receipt all use. A card that is not published comes back as ok:false under the code card_rejected, never retryable, with every finding named in the error's problems.
|
|
717
|
+
description: "Publishes one product, or says what is wrong with the card. Republishing under the same merchant_item_id is how a card is changed rather than how a second one appears. The catalog identifier comes back beside ok, and from then on it is what an agent, a purchase and a receipt all use. A card that is not published comes back as ok:false under the code card_rejected, never retryable, with every finding named in the error's problems. Three findings this can come back with are not about the card at all. A merchant who has not set the name their products are sold under gets no_seller_name, and the way past it is POST /v0/seller-name: a card published without one reaches a buyer's agent inside a payment request that names no seller. On a deployment that settles on a real chain, a merchant who has set no wallet gets no_payout_wallet, with POST /v0/payout-wallet as the way past it: the money from that card's sales is paid to the merchant's own address directly, and without one there is nowhere for it to go. On the live deployment, a merchant the operator has not admitted once gets no_operator_approval. That decision has no merchant API: test publication remains available, while live publication remains closed until the operator grants it. Every applicable finding comes back in the same problems list as whatever is wrong with the card, so one answer carries everything standing between this card and the catalog.",
|
|
684
718
|
request: CardSchema,
|
|
685
719
|
response: { document: PublishResultSchema },
|
|
686
720
|
},
|
|
@@ -804,7 +838,7 @@ export const API_ROUTES = Object.freeze({
|
|
|
804
838
|
method: "GET",
|
|
805
839
|
path: "/v0/orders",
|
|
806
840
|
auth: "merchant_key",
|
|
807
|
-
description: "Orders and the states they are in. With open=true, only the ones
|
|
841
|
+
description: "Orders and the states they are in. With open=true, only the ones a restarted worker should walk — ones the merchant was handed and has not finished, which includes the two that stay open after the purchase itself is over, an order owing a refund and one delivered but never paid for. An order that was priced and never paid, and never reached the handler, is not in that narrowing; it is readable by its identifier, where its status is the buyer's word for a purchase that has not finished. One kind of order is not in this list at all, with or without the flag: one that closed before anybody named a price for it, because the product was gone or a price question went unanswered. Every row here is written in a document that carries a sale price and those orders have none, so they are readable one at a time by their identifier, where the refusal says what became of them. A merchant reconciling against this list is reconciling against the orders that were priced.",
|
|
808
842
|
query: OrderListQuerySchema,
|
|
809
843
|
response: { document: OrderListSchema },
|
|
810
844
|
},
|
|
@@ -874,7 +908,7 @@ export const API_ROUTES = Object.freeze({
|
|
|
874
908
|
method: "POST",
|
|
875
909
|
path: "/x402/:item_id/purchase",
|
|
876
910
|
auth: "none",
|
|
877
|
-
description: "Buying one product. The payment is what stands in for authorisation, so there is no key on this call. It begins with the payment exchange of the x402 protocol: a call with no payment on it is answered with a challenge, which travels in a header and carries no document. What a paid purchase is answered with is the state of the order it made — the same document the status route answers with, whatever the card's mode and whether the purchase ended in the goods or in something else, so an agent that bought and an agent that came back later read one shape. No receipt of ours is in it: a receipt is the merchant's record of the sale and is read behind the merchant's key. What an agent is told about its own money is the price and the word for whether that money was real, and, where the payment executed as the last step of this exchange, the settlement the payment layer signs into a header on this answer — a card whose money moves as the order is opened has already spent that step, so no settlement comes back here and the two fields are the whole of it. The address answers on GET as well as on POST, because that is how the validators and crawlers that list a paid resource ask for it. An unpaid call that carries no document — a GET, or a POST with nothing or with an empty document — is answered with the challenge and never a purchase, and a GET is never read for payment; the challenge describes the purchase, which is a POST with a JSON body. An unpaid POST that carries that document is answered with the price of the very order it opened, and a document of some other shape is refused with the fields that are wrong. A product that is not on sale answers neither method with a challenge: it is refused, so that a catalog built from these challenges never carries a product nobody can buy.",
|
|
911
|
+
description: "Buying one product. The payment is what stands in for authorisation, so there is no key on this call. It begins with the payment exchange of the x402 protocol: a call with no payment on it is answered with a challenge, which travels in a header and carries no document. What a paid purchase is answered with is the state of the order it made — the same document the status route answers with, whatever the card's mode and whether the purchase ended in the goods or in something else, so an agent that bought and an agent that came back later read one shape. That document names, in status_url, the whole address where the order is read again, which is where goods that come later are collected. No receipt of ours is in it: a receipt is the merchant's record of the sale and is read behind the merchant's key. What an agent is told about its own money is the price and the word for whether that money was real, and, where the payment executed as the last step of this exchange, the settlement the payment layer signs into a header on this answer — a card whose money moves as the order is opened has already spent that step, so no settlement comes back here and the two fields are the whole of it. The address answers on GET as well as on POST, because that is how the validators and crawlers that list a paid resource ask for it. An unpaid call that carries no document — a GET, or a POST with nothing or with an empty document — is answered with the challenge and never a purchase, and a GET is never read for payment; the challenge describes the purchase, which is a POST with a JSON body. An unpaid POST that carries that document is answered with the price of the very order it opened, and a document of some other shape is refused with the fields that are wrong. A product that is not on sale answers neither method with a challenge: it is refused, so that a catalog built from these challenges never carries a product nobody can buy.",
|
|
878
912
|
request: PurchaseRequestSchema,
|
|
879
913
|
also_answers_on: ["GET"],
|
|
880
914
|
response: { document: AgentOrderStatusSchema },
|
|
@@ -883,7 +917,7 @@ export const API_ROUTES = Object.freeze({
|
|
|
883
917
|
method: "GET",
|
|
884
918
|
path: "/x402/orders/:order_id/status",
|
|
885
919
|
auth: "order_id",
|
|
886
|
-
description: "What became of a purchase, for the agent that made it: where the order stands, what it sold for, and the goods once they are the buyer's. It is the route an agent that bought a product whose goods come later collects them on, and without it half a catalogue takes money and hands back an order nobody can act on.
|
|
920
|
+
description: "What became of a purchase, for the agent that made it: where the order stands, what it sold for, and the goods once they are the buyer's. It is the route an agent that bought a product whose goods come later collects them on, and without it half a catalogue takes money and hands back an order nobody can act on. Every answer that carries the order document names this address in status_url, whole and ready to call, the purchase's own answer included. An order whose goods come later is owed them by the delivery deadline its card carried when the order was opened, counted from its payment: fulfill_deadline_seconds where the card names one, and a day where it names none. An order still without goods at that deadline becomes refund_due, and a paid order the merchant refuses or leaves behind becomes it sooner: the merchant owes the buyer the goods or the money back. That is not an ending, and it carries no further deadline. Goods the merchant delivers after it still appear here and settle the debt, and the order becomes delivered. Nor does refund_due say whether the money has come back: the merchant returns it from their own wallet, the gateway has no way yet to record that they did, and until it has one no order moves on to refunded — a buyer already paid back still reads refund_due here. So an agent holding refund_due can still collect goods here, nothing here tells it when to stop asking, and its own wallet is where a refund shows. Knowing the order's identifier is the proof (ADR-0011), so this call takes no key: an agent has no account and no registration, and the identifier is handed to exactly one party. Two things follow for whoever mounts it. Which door a call is behind is read off auth and never off the address, whatever the prefixes happen to agree on today. And an identifier that names no order must be answered exactly as any other unknown one is, or the refusal becomes a way of counting the orders behind it.",
|
|
887
921
|
response: { document: AgentOrderStatusSchema },
|
|
888
922
|
},
|
|
889
923
|
});
|
package/dist/index.d.ts
CHANGED
package/dist/order-status.js
CHANGED
|
@@ -68,8 +68,10 @@ export const ORDER_STATUSES = Object.freeze([
|
|
|
68
68
|
*/
|
|
69
69
|
"rejected",
|
|
70
70
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
71
|
+
* Nobody can say whether the buyer was charged: the payment network was
|
|
72
|
+
* asked and never answered. The order may still be open — the goods may
|
|
73
|
+
* already be made — and a later read can still move. Closed is not what
|
|
74
|
+
* this word says.
|
|
73
75
|
*
|
|
74
76
|
* Deliberately not `rejected`, and this is the fifth gate in one value. An
|
|
75
77
|
* agent told its purchase did not happen goes and buys the same thing
|
|
@@ -88,7 +90,18 @@ export const ORDER_STATUSES = Object.freeze([
|
|
|
88
90
|
"expired",
|
|
89
91
|
/** The merchant left, and orders still open closed with them. */
|
|
90
92
|
"cancelled",
|
|
91
|
-
/**
|
|
93
|
+
/**
|
|
94
|
+
* The money moved and the goods have not come: the merchant owes the buyer
|
|
95
|
+
* the goods or the money back. Not an ending, and it carries no deadline of
|
|
96
|
+
* its own. Goods the merchant delivers after it still reach the buyer, settle
|
|
97
|
+
* the debt and make the order `delivered`.
|
|
98
|
+
*
|
|
99
|
+
* What it cannot say is whether the money has already gone back. The
|
|
100
|
+
* merchant pays a refund from their own wallet and the gateway has no way yet
|
|
101
|
+
* to record that they did, so until it has one nothing moves an order on to
|
|
102
|
+
* `refunded`, and a buyer the merchant has already paid back still reads
|
|
103
|
+
* this word.
|
|
104
|
+
*/
|
|
92
105
|
"refund_due",
|
|
93
106
|
/** That debt has since been paid back to the buyer. */
|
|
94
107
|
"refunded",
|
package/dist/results.js
CHANGED
|
@@ -161,7 +161,8 @@ export const ProblemSchema = z
|
|
|
161
161
|
* value, and it covers two kinds of finding that a merchant tells apart by
|
|
162
162
|
* the words rather than by the shape: one about the whole of what was
|
|
163
163
|
* sent, and one about the merchant sending it — their having set no name
|
|
164
|
-
* for buyers to read,
|
|
164
|
+
* for buyers to read, no wallet for their sales to be paid into, or no
|
|
165
|
+
* operator approval for the live catalogue.
|
|
165
166
|
* Leaving the field out entirely would make an empty path
|
|
166
167
|
* indistinguishable from a path nobody filled in.
|
|
167
168
|
*/
|
|
@@ -172,7 +173,7 @@ export const ProblemSchema = z
|
|
|
172
173
|
message: z.string().regex(/\S/, "a finding carries an explanation a person can read"),
|
|
173
174
|
})
|
|
174
175
|
.meta({
|
|
175
|
-
description: 'One thing wrong with what was sent: where it is, a code for the program that reads it, and the same finding in words for the person who has to fix it. The path names the field, innermost last — ["params", "email", "type"] — and an empty path is a statement rather than a missing value: the finding is about the whole of what was sent, or about the sender — a merchant with no name set for buyers,
|
|
176
|
+
description: 'One thing wrong with what was sent: where it is, a code for the program that reads it, and the same finding in words for the person who has to fix it. The path names the field, innermost last — ["params", "email", "type"] — and an empty path is a statement rather than a missing value: the finding is about the whole of what was sent, or about the sender — a merchant with no name set for buyers, no wallet set for their sales to be paid into, or no operator approval for the live catalogue is refused with an empty path too — and not about any one field, which is also what a document that could not be read at all produces. The field is always present for that reason, because an absent path and an empty one would be indistinguishable. Findings never travel alone: they arrive as the problems list inside the error of a call that refused what it was handed — a card that was not published, a delivery that is not what its card declares, a body or a set of purchase parameters that did not fit.',
|
|
176
177
|
});
|
|
177
178
|
/**
|
|
178
179
|
* Why a call did not go through: a code to branch on, a sentence to print, and
|
|
@@ -202,7 +203,7 @@ export const CallErrorSchema = z.strictObject({
|
|
|
202
203
|
code: z.string().regex(/\S/, "an error carries a code").meta({
|
|
203
204
|
// Same reason as the refusal code: the dictionary travels with the field
|
|
204
205
|
// or it does not reach the reader the export exists for.
|
|
205
|
-
description: 'Why the call did not go through. The set is open, and five are promised to mean one thing each — but not on the same calls, and which call a code can arrive on is part of what is promised about it. Publishing a card is refused with one word and no other: "card_rejected" (the card was not published, and every finding standing between it and the catalog is named in the error\'s problems — the fields at fault, and the merchant\'s own missing name
|
|
206
|
+
description: 'Why the call did not go through. The set is open, and five are promised to mean one thing each — but not on the same calls, and which call a code can arrive on is part of what is promised about it. Publishing a card is refused with one word and no other: "card_rejected" (the card was not published, and every finding standing between it and the catalog is named in the error\'s problems — the fields at fault, and the merchant\'s own missing name, payout wallet or live operator approval where those are what is missing; it is never retryable, because the same card gets the same answer and what changes the outcome is fixing what the problems name). The calls that close an order — delivering, refusing, taking one on — are refused with the other four, and never with the first: "refund_already_settled" (the debt was paid back, so there is nothing left to deliver against). "order_already_closed" (the order reached an ending that no call reopens). "not_applicable_in_mode" (the call does not exist for this card\'s mode — refusing separately does not, in the synchronous one, where the handler\'s own answer is the refusal). "delivery_does_not_match_card" (the goods are not the ones the card for this order declares it delivers — nothing was written down, the problems name the fields that did not fit, and the message says whether the order still stands or has already ended). The last of those is retryable in a different sense from a lost connection: the call arrived and was understood, so sending the same goods again gives the same refusal, and what clears it is delivering what the card declares. It is not retryable at all where the order has already ended, because there is nothing left to deliver against.',
|
|
206
207
|
}),
|
|
207
208
|
message: z.string().regex(/\S/, "an error carries an explanation a person can read"),
|
|
208
209
|
retryable: z.boolean(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuanu-ai/agentify-contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Agentify wire contract as code: the schemas for cards, orders, price checks and receipts that the gateway and the merchant SDK both read.",
|
|
6
6
|
"keywords": [
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"zod-schemas",
|
|
10
10
|
"json-schema"
|
|
11
11
|
],
|
|
12
|
-
"homepage": "https://
|
|
12
|
+
"homepage": "https://agentify.ad/docs/",
|
|
13
13
|
"license": "Apache-2.0",
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|