@nuanu-ai/agentify 0.2.8 → 0.3.1

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,25 +1,28 @@
1
1
  /**
2
2
  * Is this card enough for an agent to buy from?
3
3
  *
4
- * The check is the contracts schema and nothing beside it. A second opinion
5
- * written here would be a second definition of a complete card, and the day the
6
- * two disagreed a merchant would pass one and be refused by the other.
4
+ * The check is the contracts schema and the contract's price rule, and nothing
5
+ * beside them. A second opinion written here would be a second definition of a
6
+ * complete card, and the day the two disagreed a merchant would pass one and be
7
+ * refused by the other. The price rule is read here for exactly that reason:
8
+ * it is the gateway's door that applies it rather than the schema, and a check
9
+ * that skipped it would pass a card priced at zero that publishing refuses.
7
10
  *
8
11
  * What the check cannot see is worth stating, because a merchant reading a
9
12
  * short list of findings would otherwise assume it is the whole list. A card is
10
13
  * checked in two stages: first its shape — which fields are there, what they
11
14
  * hold, whether any field was invented — and then the rules that compare one
12
15
  * field against another, such as a delivery deadline being allowed only on the
13
- * modes that wait. The second stage is only reached when the first passes. So a
14
- * card that failed on its shape may still have a finding waiting behind the
15
- * ones it was given, and the report says so instead of implying a clean second
16
- * run. A card that passes has passed both stages and there is nothing behind
17
- * it.
16
+ * modes that wait, and the price rule. The second stage is only reached when
17
+ * the first passes. So a card that failed on its shape may still have a finding
18
+ * waiting behind the ones it was given, and the report says so instead of
19
+ * implying a clean second run. A card that passes has passed both stages and
20
+ * there is nothing behind it.
18
21
  *
19
22
  * What no local check can decide at all: whether the gateway will accept the
20
- * card. Publishing is the authority — a currency we do not settle in, a
21
- * merchant key already in use, a policy nobody has written into a schema — and
22
- * this check makes no claim about any of that.
23
+ * card. Publishing is the authority — a merchant key already in use, a policy
24
+ * nobody has written into the contract — and this check makes no claim about
25
+ * any of that.
23
26
  */
24
27
  import { type Problem } from "@nuanu-ai/agentify-contracts";
25
28
  export interface CardCheck {
@@ -1,29 +1,34 @@
1
1
  /**
2
2
  * Is this card enough for an agent to buy from?
3
3
  *
4
- * The check is the contracts schema and nothing beside it. A second opinion
5
- * written here would be a second definition of a complete card, and the day the
6
- * two disagreed a merchant would pass one and be refused by the other.
4
+ * The check is the contracts schema and the contract's price rule, and nothing
5
+ * beside them. A second opinion written here would be a second definition of a
6
+ * complete card, and the day the two disagreed a merchant would pass one and be
7
+ * refused by the other. The price rule is read here for exactly that reason:
8
+ * it is the gateway's door that applies it rather than the schema, and a check
9
+ * that skipped it would pass a card priced at zero that publishing refuses.
7
10
  *
8
11
  * What the check cannot see is worth stating, because a merchant reading a
9
12
  * short list of findings would otherwise assume it is the whole list. A card is
10
13
  * checked in two stages: first its shape — which fields are there, what they
11
14
  * hold, whether any field was invented — and then the rules that compare one
12
15
  * field against another, such as a delivery deadline being allowed only on the
13
- * modes that wait. The second stage is only reached when the first passes. So a
14
- * card that failed on its shape may still have a finding waiting behind the
15
- * ones it was given, and the report says so instead of implying a clean second
16
- * run. A card that passes has passed both stages and there is nothing behind
17
- * it.
16
+ * modes that wait, and the price rule. The second stage is only reached when
17
+ * the first passes. So a card that failed on its shape may still have a finding
18
+ * waiting behind the ones it was given, and the report says so instead of
19
+ * implying a clean second run. A card that passes has passed both stages and
20
+ * there is nothing behind it.
18
21
  *
19
22
  * What no local check can decide at all: whether the gateway will accept the
20
- * card. Publishing is the authority — a currency we do not settle in, a
21
- * merchant key already in use, a policy nobody has written into a schema — and
22
- * this check makes no claim about any of that.
23
+ * card. Publishing is the authority — a merchant key already in use, a policy
24
+ * nobody has written into the contract — and this check makes no claim about
25
+ * any of that.
23
26
  */
24
- import { CardSchema } from "@nuanu-ai/agentify-contracts";
27
+ import { CardSchema, priceProblemsOf } from "@nuanu-ai/agentify-contracts";
25
28
  import { problemsOf } from "./schema.js";
26
29
  export const checkCard = (card) => {
27
30
  const result = CardSchema.safeParse(card);
28
- return { problems: result.success ? [] : problemsOf(result.error.issues) };
31
+ return {
32
+ problems: result.success ? priceProblemsOf(result.data.price) : problemsOf(result.error.issues),
33
+ };
29
34
  };
package/dist/verify.js CHANGED
@@ -118,19 +118,23 @@ const USAGE = [
118
118
  * that route promises is worth repeating exactly, because every part of it is
119
119
  * easy to overstate. Whose cards it returns is settled: the merchant whose key
120
120
  * the call was made with, and nobody else. A card reaches that list by being accepted at
121
- * `publish_card`, which parses the same `CardSchema` this package parses, so
122
- * the cards on it passed this check on the day they went out — which is not
123
- * the same as passing it now, because the schema can move, nothing parses a
124
- * stored card again on the way back out, and a command that builds no client
125
- * can never learn which version of the contract the gateway is speaking. And
126
- * publishing is more than this check: it can refuse a card for reasons no
127
- * schema carries, which `checkCard` says in its own words.
121
+ * `publish_card`, which parses the same `CardSchema` and applies the same
122
+ * price rule this package does, so the cards on it passed this check on the
123
+ * day they went out — which is not the same as passing it now. The schema can
124
+ * move, and the price rule is applied only at publication: a stored card is
125
+ * parsed again on its way back out against the schema alone, so a card
126
+ * published before the price rule tightened is read back as it was, and one
127
+ * that no longer fits a schema that moved fails that read. And a
128
+ * command that builds no client can never learn which version of the contract
129
+ * the gateway is speaking. Publishing is more than this check, too: it can
130
+ * refuse a card for reasons the contract does not carry, which `checkCard`
131
+ * says in its own words.
128
132
  *
129
133
  * Taking no key is a choice and not a hole, which is worth saying here because
130
134
  * the first line of the message reads like a limitation somebody would set out
131
- * to remove. A check that read published cards over that route would always
132
- * pass — they got onto it by passing this very schema — and a green that cannot
133
- * fail teaches a merchant to stop reading it. What would earn a keyed mode is a
135
+ * to remove. A check that read published cards over that route would all but
136
+ * always pass — they got onto it by passing this very check — and a green that
137
+ * cannot fail teaches a merchant to stop reading it. What would earn a keyed mode is a
134
138
  * dry run of publishing, which can refuse for reasons no schema carries; there
135
139
  * is no such route (`docs/research/00-open-questions.md`).
136
140
  *
package/dist/worker.js CHANGED
@@ -50,7 +50,7 @@
50
50
  * delivered no envelope to anybody. That retry is the backoff in
51
51
  * `backoff.ts` and nothing more.
52
52
  */
53
- import { HandlerAnswerSchema, PROTOTYPE_KEY_IS_DROPPED, QuoteResponseSchema, } from "@nuanu-ai/agentify-contracts";
53
+ import { HandlerAnswerSchema, PROTOTYPE_KEY_IS_DROPPED, priceProblemsOf, QuoteResponseSchema, } from "@nuanu-ai/agentify-contracts";
54
54
  import { retryDelayMs } from "./backoff.js";
55
55
  import { contractVersion, speaksContract } from "./contract.js";
56
56
  import { describeProblems, problemsOf } from "./schema.js";
@@ -423,12 +423,20 @@ deadlineMs = POLL_DEADLINE_MS) => {
423
423
  // gateway's complaint about a document, which reads as our fault and
424
424
  // names the merchant's field only inside a quoted blob.
425
425
  const checked = QuoteResponseSchema.safeParse(answer);
426
- if (!checked.success) {
426
+ // The gateway holds the price to the rule a card's price meets, outside the
427
+ // schema; applied here too, a zero or a missing cent is named as the
428
+ // merchant's own field rather than coming back as a call that failed.
429
+ const problems = checked.success
430
+ ? checked.data.available
431
+ ? priceProblemsOf(checked.data.price)
432
+ : []
433
+ : problemsOf(checked.error.issues);
434
+ if (!checked.success || problems.length > 0) {
427
435
  report({
428
436
  kind: WORKER_PROBLEM_KINDS.HANDLER_ANSWER_REFUSED,
429
437
  fatal: false,
430
438
  subject: question.price_id,
431
- message: `the price handler's answer for question ${question.price_id} is not one the contract carries, so no price was sent:\n${describeProblems(problemsOf(checked.error.issues))}`,
439
+ message: `the price handler's answer for question ${question.price_id} is not one the contract carries, so no price was sent:\n${describeProblems(problems)}`,
432
440
  });
433
441
  return;
434
442
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuanu-ai/agentify",
3
- "version": "0.2.8",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "Sell your existing products to AI agents: publish product cards to an x402 storefront and fill the paid orders from your own service.",
6
6
  "keywords": [
@@ -36,7 +36,7 @@
36
36
  "access": "public"
37
37
  },
38
38
  "dependencies": {
39
- "@nuanu-ai/agentify-contracts": "0.5.0"
39
+ "@nuanu-ai/agentify-contracts": "0.7.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "vitest": "^4.1.11",